[BZOJ1056][HAOI2008]排名系统(平衡树splay)
来源:互联网 发布:淘宝历史宝贝精灵 编辑:程序博客网 时间:2024/05/29 21:28
题目描述
传送门
题解
同BZOJ1862
不知道为什么,题目一样,时限比较长,所以我之前那个T一组的代码也过了= =
闲着无聊再贴一遍= =
代码
#include<iostream>#include<cstring>#include<cstdio>#include<map>using namespace std;const int max_n=3e5+5;const int INF=2e9;map <string,int> list,score;map <int,string> name;int n,tot,totplayer;string Name,s;int Score;int f[max_n],ch[max_n][2],size[max_n],key[max_n],player[max_n];int root,sz;int printtot,printcnt;inline bool get(int x){ return ch[ f[x] ][1]==x;}inline void update(int x){ if (x){ size[x]=1; if (ch[x][0]) size[x]+=size[ ch[x][0] ]; if (ch[x][1]) size[x]+=size[ ch[x][1] ]; }}inline void rotate(int x){ int old=f[x],oldf=f[old],which=get(x); ch[old][which]=ch[x][which^1]; f[ ch[old][which] ]=old; ch[x][which^1]=old; f[old]=x; f[x]=oldf; if (oldf) ch[oldf][ ch[oldf][1]==old ]=x; update(old); update(x);}inline void splay(int x,int tar){ for (int fa;(fa=f[x])!=tar;rotate(x)) if (f[fa]!=tar) rotate( (get(x)==get(fa)) ?fa:x); if (!tar) root=x;}//返回分数为x,名字编号为y的点的排名inline int find(int x,int y){ int now=root,ans=0; while (1){ if (x<key[now]) now=ch[now][0]; else{ if (x==key[now]){ if (y==player[now]){ if (ch[now][0]) ans+=size[ ch[now][0] ]; return ans+1; } if (y<player[now]) now=ch[now][0]; else{ if (ch[now][0]) ans+=size[ ch[now][0] ]; ans+=1; now=ch[now][1]; } } else{ if (ch[now][0]) ans+=size[ ch[now][0] ]; ans+=1; now=ch[now][1]; } } }}//权值小于x,且最靠后 inline int Insert_Find_Pre(int x){ int now=root,ans; while (1){ if (key[now]<x){ ans=now; if (ch[now][1]) now=ch[now][1]; else break; } else if (ch[now][0]) now=ch[now][0]; else break; } return ans;}//权值大于或等于x,且最靠前 inline int Insert_Find_Next(int x){ int now=root,ans; while (1){ if (key[now]>=x){ ans=now; if (ch[now][0]) now=ch[now][0]; else break; } else if (ch[now][1]) now=ch[now][1]; else break; } return ans;}//权值小于x,或者权值等于x且序号小于x,且最靠后 inline int Delete_Find_Pre(int x,int Name){ int now=root,ans; while (1){ if (key[now]<x||key[now]==x&&player[now]<Name){ ans=now; if (ch[now][1]) now=ch[now][1]; else break; } else if (ch[now][0]) now=ch[now][0]; else break; } return ans;} //权值大于x,或者权值等于x且序号大于于x,且最靠后 inline int Delete_Find_Next(int x,int Name){ int now=root,ans; while (1){ if (key[now]>x||key[now]==x&&player[now]>Name){ ans=now; if (ch[now][0]) now=ch[now][0]; else break; } else if (ch[now][1]) now=ch[now][1]; else break; } return ans;} inline void insert(int x,int Name){ if (root==0){ root=++sz; f[sz]=ch[sz][0]=ch[sz][1]=0; size[sz]=1; key[sz]=x; player[sz]=Name; return; } if (!ch[root][0]&&!ch[root][1]){ ch[root][ key[root]<x ]=++sz; f[sz]=root; ch[sz][0]=ch[sz][1]=0; size[sz]=1; key[sz]=x; player[sz]=Name; update(root); return; } int aa=Insert_Find_Pre(x); int bb=Insert_Find_Next(x); splay(aa,0); splay(bb,aa); ch[ ch[root][1] ][0]=++sz; f[sz]=ch[root][1]; ch[sz][0]=ch[sz][1]=0; size[sz]=1; key[sz]=x; player[sz]=Name; update(ch[root][1]); update(root);}inline void del(int x,int Name){ int aa=Delete_Find_Pre(x,Name); int bb=Delete_Find_Next(x,Name); splay(aa,0); splay(bb,aa); ch[ ch[root][1] ][0]=0; update(ch[root][1]); update(root);}//返回排名为x的点的编号inline int findnum(int x){ int now=root,ans; while (1){ if (ch[now][0]&&x<=size[ ch[now][0] ]) now=ch[now][0]; else{ int temp=1; if (ch[now][0]) temp+=size[ ch[now][0] ]; if (x<=temp) return now; x-=temp; now=ch[now][1]; } }} inline void print(int x){ int now=x; if (ch[now][1]) print(ch[now][1]); printtot++; string s=name[player[now]]; int len=s.length(); for (int i=0;i<len;++i) putchar(s[i]); if (printtot!=printcnt) putchar(' '); if (ch[now][0]) print(ch[now][0]);}inline void Query(int L,int R){ int y=totplayer-L+1; int x=totplayer-(L+R-1)+1; //x-1 y+1 int aa=findnum(x); int bb=findnum(y+2); splay(aa,0); splay(bb,aa); printtot=0; printcnt=R; print( ch[ ch[root][1] ][0] );}int main(){// freopen("input.txt","r",stdin);// freopen("my.out","w",stdout); scanf("%d",&n); insert(-INF,INF+2); insert(INF,INF+1); tot=250000+1; for (int i=1;i<=n;++i){ char c=getchar(); while (c!='+'&&c!='?') c=getchar(); if (c=='+'){ Name=""; char cc; while (1){ cc=getchar(); if (cc==' ') break; Name=Name+cc; } scanf("%d",&Score); if (list[Name]){ del( score[Name],list[Name] ); list[Name]=--tot; name[tot]=Name; score[Name]=Score; insert( Score,list[Name] ); } else{ totplayer++; list[Name]=--tot; name[tot]=Name; score[Name]=Score; insert( Score,list[Name] ); } } else{ Name=""; char cc; while (1){ cc=getchar(); if (cc=='\n') break; Name+=cc; } if (Name[0]>='0'&&Name[0]<='9'){ int Index=0; int len=Name.length(); for (int j=0;j<len;++j) Index=Index*10+Name[j]-'0'; int L=Index; int R=min(totplayer-Index+1,10); Query(L,R); putchar('\n'); } else{ int ans=find( score[Name],list[Name] )-1; printf("%d\n",totplayer-ans+1); } } } return 0; }
#include<iostream>#include<cstring>#include<cstdio>#include<map>using namespace std;const int max_n=3e5+5;const int INF=2e9;map <string,int> list,score;map <int,string> name;int n,tot,totplayer;string Name,s;int Score;int f[max_n],ch[max_n][2],size[max_n],key[max_n];int root,sz;int printtot,printcnt;inline void clear(int x){ ch[x][0]=ch[x][1]=f[x]=size[x]=key[x]=0;}inline bool get(int x){ return ch[ f[x] ][1]==x;}inline void update(int x){ if (x){ size[x]=1; if (ch[x][0]) size[x]+=size[ ch[x][0] ]; if (ch[x][1]) size[x]+=size[ ch[x][1] ]; }}inline void rotate(int x){ int old=f[x],oldf=f[old],which=get(x); ch[old][which]=ch[x][which^1]; f[ ch[old][which] ]=old; ch[x][which^1]=old; f[old]=x; f[x]=oldf; if (oldf) ch[oldf][ ch[oldf][1]==old ]=x; update(old); update(x);}inline void splay(int x,int tar){ for (int fa;(fa=f[x])!=tar;rotate(x)) if (f[fa]!=tar) rotate( (get(x)==get(fa)) ?fa:x); if (!tar) root=x;}inline int insert(int x){ if (root==0){ sz++; ch[sz][0]=ch[sz][1]=f[sz]=0; root=sz; size[sz]=1; key[sz]=x; return sz; } int now=root,fa=0; while(1){ fa=now; now=ch[now][key[now]<x]; if (now==0){ sz++; ch[sz][0]=ch[sz][1]=0; f[sz]=fa; size[sz]=1; ch[fa][key[fa]<x]=sz; key[sz]=x; update(fa); splay(sz,0); break; } } return sz;}inline int pre(){ int now=ch[root][0]; while (ch[now][1]) now=ch[now][1]; return now;}inline void del(int x,int cnt){ splay(cnt,0); if (!ch[root][0]&&!ch[root][1]){ clear(root); root=0; return; } if (!ch[root][0]){ int oldroot=root; root=ch[root][1]; f[root]=0; clear(oldroot); return; } else if (!ch[root][1]){ int oldroot=root; root=ch[root][0]; f[root]=0; clear(oldroot); return; } int leftbig=pre(),oldroot=root; splay(leftbig,0); ch[root][1]=ch[oldroot][1]; f[ch[oldroot][1]]=root; clear(oldroot); update(root); }//返回排名为x的点的编号inline int findnum(int x){ int now=root,ans; while (1){ if (ch[now][0]&&x<=size[ ch[now][0] ]) now=ch[now][0]; else{ int temp=1; if (ch[now][0]) temp+=size[ ch[now][0] ]; if (x<=temp) return now; x-=temp; now=ch[now][1]; } }} inline void print(int x){ int now=x; if (ch[now][1]) print(ch[now][1]); printtot++; string s=name[now]; int len=s.length(); for (int i=0;i<len;++i) putchar(s[i]); if (printtot!=printcnt) putchar(' '); if (ch[now][0]) print(ch[now][0]);}inline void Query(int L,int R){ int y=totplayer-L+1; int x=totplayer-(L+R-1)+1; //x-1 y+1 int aa=findnum(x); int bb=findnum(y+2); splay(aa,0); splay(bb,aa); printtot=0; printcnt=R; print( ch[ ch[root][1] ][0] );}int main(){// freopen("input.txt","r",stdin);// freopen("my.out","w",stdout); scanf("%d",&n); insert(-INF); insert(INF); for (int i=1;i<=n;++i){ char c=getchar(); while (c!='+'&&c!='?') c=getchar(); //list<string,int>表示名字的编号,score<string,int>表示名字的分数 //name[i]<int,string>表示编号为i的是哪个名字 if (c=='+'){ Name=""; char cc; while (1){ cc=getchar(); if (cc==' ') break; Name=Name+cc; } scanf("%d",&Score); if (list[Name]){ del( score[Name],list[Name] ); score[Name]=Score; int number=insert( Score ); list[Name]=number; name[number]=Name; } else{ totplayer++; score[Name]=Score; int number=insert( Score ); list[Name]=number; name[number]=Name; } } else{ Name=""; char cc; while (1){ cc=getchar(); if (cc=='\n') break; Name+=cc; } if (Name[0]>='0'&&Name[0]<='9'){ int Index=0; int len=Name.length(); for (int j=0;j<len;++j) Index=Index*10+Name[j]-'0'; int L=Index; int R=min(totplayer-Index+1,10); Query(L,R); putchar('\n'); } else{//查询玩家排名 splay(list[Name],0); int ans=size[ ch[root][0] ]-1; printf("%d\n",totplayer-ans); } } } return 0; }
0 0
- [BZOJ1056][HAOI2008]排名系统(平衡树splay)
- 【BZOJ1056】[HAOI2008]排名系统【Splay】【Hash】
- 【bzoj1056】[HAOI2008]排名系统
- 【BZOJ1056/BZOJ1862】【ZJOI2006】【HAOI2008】游戏排名系统 splay
- BZOJ1056: [HAOI2008]排名系统 Treap
- BZOJ1056 [HAOI2008]排名系统 treap实现map
- 【BZOJ1056&&1862】【codevs1985】排名系统,Splay+trie树
- bzoj1056&bzoj1862 游戏排名系统 哈希+splay
- [BZOJ1862][ZJOI2006]GameZ游戏排名系统(平衡树splay)
- BZOJ 1056 [HAOI2008] 排名系统 Tire树+Treap(Splay)
- [HAOI2008] 排名系统 & [ZJOI2006] GameZ游戏排名系统 [SPLAY]【数据结构】
- bzoj1056(挖个坑wa+tle,平衡树)
- [BZOJ1056]=[BZOJ1862]排名系统
- 【BZOJ1056/1862】【排名系统】【hash+treap】
- [HAOI2008]排名系统
- [HAOI2008]排名系统
- 1056: [HAOI2008]排名系统
- [题解]bzoj1056/1862 Zjoi2006 GameZ游戏排名系统
- 内链接和外连接
- 15电气李书鹏 作业1
- 设计模式第八堂课
- Codeforces 301A Yaroslav and Sequence 【思维】
- git工作笔记
- [BZOJ1056][HAOI2008]排名系统(平衡树splay)
- MyBatis逆向工程
- Android开发 Activity的四种启动模式
- DB2存储过程入门
- 类的静态成员
- Qt之模型/视图(自定义按钮)
- 寻找Jar或者查询maven依赖写法的网址
- 转载:一个清华学生留学香港后对人生的思考
- Java web 运行时访问不了.dll库