BZOJ 1862/1056 ZJOI 2006 GameZ游戏排名系统/ HAOI 2008 排名系统 Treap (双倍经验)

题目大意:维护一种游戏排名系统,为他们的得分排序,若得分一样,则时间早的优先。有的时候要查询一个人是第几名,或者一段名次都是谁。

思路:拿到题一看就知道是暴力Treap乱搞,但是一查不知道看到了谁的文章,说Treap会T,我就战战兢兢的写了Splay,结果T了,拿到数据发现被一个点卡了100s。于是怒写Treap,1.2s怒切。

PS:千万不要相信谣言。。

CODE:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 300010
#define MO 299997
#define BASE 133
#define SIZE(a) ((a) == NULL ? 0:(a)->size)
using namespace std;

unsigned long long GetHash(char *s);

struct HashSet{
	int head[MAX],total;
	int next[MAX];
	unsigned long long hash[MAX];
	char src[MAX][12];

	int Insert(char *s) {
		unsigned long long _hash = GetHash(s);
		int x = _hash % MO;
		for(int i = head[x]; i; i = next[i])
			if(hash[i] == _hash)
				return i;
		next[++total] = head[x];
		hash[total] = _hash;
		head[x] = total;
		strcpy(src[total],s);
		return total;
	}
}map;

struct Treap{
	int random,val,T,name;
	int size;
	Treap *son[2];

	Treap(int _,int __,int ___):val(_),T(__),name(___) {
		size = 1;
		son[0] = son[1] = NULL;
		random = rand();
	}
	int Compare(int _val,int _T) {
		if(_val == val) {
			if(T == _T)	return -1;
			return T < _T;
		}
		return val > _val;
	}
	void Maintain() {
		size = 1;
		if(son[0] != NULL)	size += son[0]->size;
		if(son[1] != NULL)	size += son[1]->size;
	}
}*root = NULL;

int cnt;
int score;
char c,name[12];

int now[MAX],_time[MAX];

unsigned long long GetHash(char *s)
{
	unsigned long long re = 0;
	while(*s != '\0')
		re = re * BASE + *s++;
	return re;
}

inline void Rotate(Treap *&a,bool dir)
{
	Treap *k = a->son[!dir];
	a->son[!dir] = k->son[dir];
	k->son[dir] = a;
	a->Maintain(),k->Maintain();
	a = k;
}

void Insert(Treap *&a,int score,int t,int name)
{
	if(a == NULL) {
		a = new Treap(score,t,name);
		return ;
	}
	int dir = a->Compare(score,t);
	Insert(a->son[dir],score,t,name);
	if(a->son[dir]->random > a->random)
		Rotate(a,!dir);
	a->Maintain();
}

void Delete(Treap *&a,int score,int t)
{
	int dir = a->Compare(score,t);
	if(dir != -1)
		Delete(a->son[dir],score,t);
	else {
		if(a->son[0] == NULL)	a = a->son[1];
		else if(a->son[1] == NULL)	a = a->son[0];
		else {
			int _ = (a->son[0]->random > a->son[1]->random);
			Rotate(a,_);
			Delete(a->son[_],score,t);
		}
	}
	if(a != NULL)	a->Maintain();
}

int Rank(Treap *a,int k)
{
	if(k <= SIZE(a->son[0]))	return Rank(a->son[0],k);
	k -= SIZE(a->son[0]);
	if(k == 1)	return a->name;
	return Rank(a->son[1],k - 1);
}

int Find(Treap *a,int score,int t)
{
	int dir = a->Compare(score,t);
	if(dir == 0)	return Find(a->son[0],score,t);
	if(dir == -1)	return SIZE(a->son[0]) + 1;
	return SIZE(a->son[0]) + 1 + Find(a->son[1],score,t);
}

int main()
{
	cin >> cnt;
	for(int i = 1; i <= cnt; ++i) {
		while(c = getchar(),c == ' ' || c == '\n' || c == '\r' || c == '\t');
		if(c == '+') {
			scanf("%s%d",name,&score);
			int x = map.Insert(name);
			if(now[x])	Delete(root,now[x],_time[x]);
			now[x] = score,_time[x] = i;
			Insert(root,now[x],_time[x],x);
		}
		else {
			c = getchar();
			ungetc(c,stdin);
			if(isdigit(c)) {
				int st,ed;
				scanf("%d",&st);
				ed = min(st + 9,map.total);
				for(int i = st; i <= ed; ++i) {
					if(i != st)	putchar(' ');
					printf("%s",map.src[Rank(root,i)]);
				}
				puts("");
			}
			else {
				scanf("%s",name);
				int x = map.Insert(name);
				printf("%d\n",Find(root,now[x],_time[x]));
			}
		}
	}
	return 0;
}

时间: 2024-11-08 10:22:33

BZOJ 1862/1056 ZJOI 2006 GameZ游戏排名系统/ HAOI 2008 排名系统 Treap (双倍经验)的相关文章

bzoj 1862/1056 [HAOI2008]排名系统

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862 很恶心的 一道题,我也不晓得自己是第几次写这题了%>_<%. 写了两种方法,平衡树+哈希和平衡树+map.哈希函数是抄别人的.比较了一下还是哈希快一些. 题意很简单,就不说了. 具体思路是,平衡树维护排名,map建立姓名和分数一一对应的关系. 求rank时题意默认是越先提交得分排名越靠前(相同得分的条件下). 具体如下: 平衡树+map 1 #include<algorit

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 Splay

Splay的基本操作,比较繁琐..... 有个一坑点,sorce会超int 1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 913  Solved: 343 [Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时,先上传记录者优先.由于新游戏的火爆,网站服务器已经难堪重负.为此

bzoj 1022: [SHOI2008]小约翰的游戏John anti_nim游戏

1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1189  Solved: 734[Submit][Status] Description 小 约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有n堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意 多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输.小约翰相当固执,他坚持认为先取的人有很大的优

BZOJ 3105:[cqoi2013]新Nim游戏

BZOJ 3105:[cqoi2013]新Nim游戏 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3105 题目大意:在传统的Nim取石子游戏中做了改变:两人刚开始可以取走任意堆石子(不包括全部)后进行传统游戏,问先手能否必胜,若必胜求出刚开始最少取多少石子. 线性基 传统Nim游戏先手必胜的前提条件为$a_0 \lxor a_1 \lxor a_2 \lxor ... \lxor a_{n-1} \neq 0$. 故若欲使新Nim游

计算机专业-世界大学学术排名,QS排名,U.S.NEWS排名

2015年美国大学计算机专业排名 计算机专业介绍:计算机涉及的领域非常广泛,其分支学科也是非常多.所以在美国将主要的专业方向分为人工智能,程序应用,计算机系统(Systems)以及计算机理论(theory)这四个部分. 每个部分又有很多的研究方向,诸如人工智能与知识工程,模式识别与图像处理软件,多媒体技术与图形学,智能信息系统工程与软件自动化,数据库与数据仓库,数据挖掘与知识发现,计算机网络技术及其应用,计算机系统与控制,信息系统安全,计算机安全等等. 这些研究方向隶属于以上四个研究方向但是分类

零之矿区区块链游戏挖矿最便宜的开发系统

零之矿区游戏app全网合一系统开发找▍梁经理159-2054-0260 微/电▍.零之矿区全自动挂机挖矿算力计算开发介绍.零之矿区挖矿系统app软件开发.零之矿区智能算力自动挖矿交易系统开发.零之矿区游戏app程序源码开发 ---专业开发公司,玩家勿扰--- 注册账户:按照注册提示操作即可,在这里,如果填入好友的邀请码,可以额外获得30个矿晶.如果不是邀请注册的玩家,系统初始赠送的矿晶只有15个喔. 注册进入游戏后,立马花10个矿晶去雇佣矿工挖矿,一天妥妥收益48个矿晶. 矿晶作用非常大,可参与

用cocos2d-html5做的消除类游戏《英雄爱消除》(1)——系统主菜单

系统主菜单如下图所示: 首先,介绍下这个主菜单,它包含了一个动画logo以及一个按钮选项,动画logo每隔1秒钟切换一张图片,点击相应的按钮选项会切换不同的游戏场景. 下面看下这个界面的源码: /** * Power by html5中文网(html5china.com) * author: jackyWHJ */ cc.dumpConfig(); var winSize; var SysMenu = cc.Layer.extend({ _hero:null, _logo:null, _logo

英伦大厦游戏英伦大厦app定制开发系统

英伦大厦游戏英伦大厦app定制开发系统(微or电 158.1500.1390 小凡团队)英伦大厦系统开发,英伦大厦模式开发,英伦大厦游戏开发,英伦大厦盖楼游戏模式开发系统,英伦大厦系统平台定制开发 英伦大厦是什么? 英伦大厦是一款经营类游戏,此游戏高度形象的还原真实百货公司的故事场景,人性化的情节设计难易适中,细致巧妙的游戏布景道具让您感受到游戏的乐趣,力求为玩家们营造出一个身临其境的百货大厦,充分将娱乐休闲与经营店铺相结合,体验感十足! 英伦大厦英文名字:British building,据说