标签:splay zjoi2006 haoi2008 游戏排名系统 排名系统
题意:自己看。
题解: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; }
【BZOJ1056/BZOJ1862】【ZJOI2006】【HAOI2008】游戏排名系统 splay
标签:splay zjoi2006 haoi2008 游戏排名系统 排名系统
原文地址:http://blog.csdn.net/vmurder/article/details/41170019