【BZOJ1056/BZOJ1862】【ZJOI2006】【HAOI2008】游戏排名系统 splay

题意:自己看。

题解:splay。

注意:…………………………我特么在?+数字时只读了一位,导致什么?11啊,?10啊全读成了1。

今天狠下心来写拍子,才,发,现,我就是个大沙茶!

先附随机数生成器,这个比较挫,能生成的数据范围比较小。

#include <ctime>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 50
#define M 12
using namespace std;
char name[N+5][M];
int n;
int main()
{
	freopen("test.in","w",stdout);
	int i,j,k;
	srand((unsigned)time(NULL));
	printf("%d\n",N);
	for(i=1;i<=26;i++)name[i][0]='A'+i-1,name[i][1]='\0';
	for(i=27;i<=50;i++)name[i][0]='A',name[i][1]='A'+i-27,name[i][2]='\0';
	for(i=1;i<=N;i++)
	{
		j=rand()%100;
		if(j<60)printf("+%s %d\n",name[++n],rand()%5000+1);
		else
		{
			printf("?");
			if(j<80)printf("%s\n",name[rand()%n+1]);
			else printf("%d\n",rand()%n+1);
		}
	}
	return 0;
}

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 250100
#define T 26
#define ls son[x][0]
#define rs son[x][1]
#define is(x) (x==son[fa[x]][1])
#define inf 0x7f7f7f7f
using namespace std;
char name[N][20];
int n,m;
struct Trie
{
	int next[N][T],note[N],root,cnt;
	int find()
	{
		int i,x,alp;
		for(x=root,i=0;name[n][i];i++)
		{
			alp=name[n][i]-'A';
			if(!next[x][alp])next[x][alp]=++cnt;
			x=next[x][alp];
		}
		if(!note[x])
		{
			note[x]=n;
			return 0;
		}
		n--;
		return note[x];
	}
}trie;
struct SPT
{
	int fa[N],son[N][2],root;
	int val[N],size[N];
	void pushup(int x)
	{
		size[x]=size[ls]+size[rs]+1;
	}
	void jo(int x,int y,int d){son[y][d]=x,fa[x]=y;}
	void rotate(int x)/* 此处没有pushup(x),留于splay中pushup */
	{
		int y=fa[x],z=fa[y],i=is(x),t=son[x][!i];
		jo(t,y,i),jo(x,z,is(y)),jo(y,x,!i);
		fa[0]=0;
		pushup(y);
	}
	void splay(int x,int k=0)
	{
		int y,z;
		while(fa[x]!=k)
		{
			y=fa[x],z=fa[y];
			if(z==k){rotate(x);break;}
			if(is(x)==is(y))rotate(y),rotate(x);
			else rotate(x),rotate(x);
		}
		pushup(x);
		if(!k)root=x;
		return ;
	}
	void newnode(int &x,int y,int w,int p)
	{
		x=p;
		fa[p]=y,son[p][0]=son[p][1]=0;
		val[p]=w,size[p]=1;
	}
	void cls()
	{
		root=fa[n=2]=1,son[1][1]=2;
		val[1]=-inf,val[2]=inf;
		size[1]=2,size[2]=1;
	}
	int pred(int x,int k=0)
	{
		splay(x);
		for(x=ls;rs;)x=rs;
		splay(x,k);
		return x;
	}
	int succ(int x,int k=0)
	{
		splay(x);
		for(x=rs;ls;)x=ls;
		splay(x,k);
		return x;
	}
	int find(int rank,int k=0)
	{
		int x=root;
		while(size[rs]+1!=rank)
		{
			if(size[rs]+1>rank)x=rs;
			else rank-=(size[rs]+1),x=ls;
		}
		splay(x,k);
		return x;
	}
	int query(int w,int k=0)/*O(1)找rank*/
	{
		int x=w;
		splay(x,k);
		return size[rs]+1;
	}
	void remove(int x)
	{
		pred(x);
		splay(x,root);
		jo(rs,root,1);
	}
	void insert(int w,int p)
	{
		int x=root;
		for(;son[x][val[x]<w];x=son[x][val[x]<w]);
		newnode(son[x][val[x]<w],x,w,p);
		splay(son[x][val[x]<w]);
	}
}spt;
int main()
{
//	freopen("test.in","r",stdin);
//	freopen("my.out","w",stdout);
	int i,j,k;
	scanf("%d",&m);
	spt.cls();
	for(i=1;i<=m;i++)
	{
		char opt=0;
		int person;
		while(opt=getchar(),opt==' '||opt=='\n'||opt=='\r'||opt=='\t');
		scanf("%s",name[++n]);
		if(opt=='+')
		{
			person=trie.find();
			scanf("%d",&k);
			if(!person)spt.insert(k,n);
			else /*if(spt.val[person]<k)*/spt.remove(person),spt.insert(k,person);
		}
		else
		{
			if('0'<=name[n][0]&&name[n][0]<='9')
			{
				for(k=j=0;name[n][j];j++)k=k*10+name[n][j]-'0';
				n--;
				int ul=min(k+9,spt.size[spt.root]-2);
				for(j=k;j<ul;j++)printf("%s ",name[spt.find(j+1)]);
				if(k<=ul)printf("%s\n",name[spt.find(ul+1)]);
			}
			else
			{
				person=trie.find();
				printf("%d\n",spt.query(person)-1);
			}
		}
	}
	return 0;
}

复制去Google翻译翻译结果

时间: 2024-10-31 09:46:21

【BZOJ1056/BZOJ1862】【ZJOI2006】【HAOI2008】游戏排名系统 splay的相关文章

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为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家

【pb_ds】bzoj1056 [HAOI2008]排名系统/bzoj1862 [Zjoi2006]GameZ游戏排名系统

STL裸题,线下AC,bzoj无限RE ing…… 1 #include<cstdio> 2 #include<cctype> 3 #include<iostream> 4 #include<string> 5 #include<ext/pb_ds/assoc_container.hpp> 6 #include<ext/pb_ds/tree_policy.hpp> 7 using namespace std; 8 using name

bzoj1056/1862 [Zjoi2006]GameZ游戏排名系统

题目链接:1,2 treap恶心题,不多说 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<queue> 9 #include<stack> 10 #

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为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时,先上传记录者优先.由于新游戏的火爆,网站服务器已经难堪重负.为此

bzoj1862/1056: [Zjoi2006]GameZ游戏排名系统

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id=1056 [题解] 写到头昏脑涨(逃 写着写着发现不仅要记录权值和哈希值还需要记录插入时间,于是强行开了两个map来映射哈希值->权值,哈希值->插入时间 好像常数很大的样子但是跑的挺快呀.. 记住无论什么操作,都要splay到根,包括询问,因为可以构造一直询问的来卡复杂度. 好像就行了

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&

【HAOI2008】排名系统

[题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入格式] 第一行是一个整数n(n>=10)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超过10个字符.Score为最多8位的正整数.

HYSBZ 1862 GameZ游戏排名系统

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1862 将相等的值放到左子树下 自然就维护了先上传排名高的条件 维护名字可以用hash 这里为了省事直接用的map 因为输出的是排名 所以要选择后序遍历 这题有剧毒 数据跟题目描述不符 我开始inf=0x3f3f3f3f wa了好久 改成2e9就a了 #include<iostream> #include<cstdio> #include<cstring> #incl

数据结构(Splay平衡树):HAOI2008 排名系统

[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入] 第一行是一个整数n(10<=n<=250000)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超