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

Description

GameZ为他们最新推出的游戏开通了一个网站。世界各地的玩家都可以将自己的游戏得分上传到网站上。这样就可以看到自己在世界上的排名。得分越高,排名就越靠前。当两个玩家的名次相同时,先上传记录者优先。由于新游戏的火爆,网站服务器已经难堪重负。为此GameZ雇用了你来帮他们重新开发一套新的核心。排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。

Input

第一行是一个整数n(n>=10)表示请求总数目。接下来n行每行包含了一个请求。请求的具体格式如下: +Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。 ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。输入文件总大小不超过2M。 NOTE:用C++的fstream读大规模数据的效率较低

Output

对于每条查询请求,输出相应结果。对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。

Sample Input

20
+ADAM 1000000 加入ADAM的得分记录
+BOB 1000000 加入BOB的得分记录
+TOM 2000000 加入TOM的得分记录
+CATHY 10000000 加入CATHY的得分记录
?TOM 输出TOM目前排名
?1 目前有记录的玩家总数为4,因此应输出第1名到第4名。
+DAM 100000 加入DAM的得分记录
+BOB 1200000 更新BOB的得分记录
+ADAM 900000 更新ADAM的得分记录(即使比原来的差)
+FRANK 12340000 加入FRANK的得分记录
+LEO 9000000 加入LEO的得分记录
+KAINE 9000000 加入KAINE的得分记录
+GRACE 8000000 加入GRACE的得分记录
+WALT 9000000 加入WALT的得分记录
+SANDY 8000000 加入SANDY的得分记录
+MICK 9000000 加入MICK的得分记录
+JACK 7320000 加入JACK的得分记录
?2 目前有记录的玩家总数为12,因此应输出第2名到第11名。
?5 输出第5名到第13名。
?KAINE 输出KAINE的排名

Sample Output

2
CATHY TOM ADAM BOB
CATHY LEO KAINE WALT MICK GRACE SANDY JACK TOM BOB
WALT MICK GRACE SANDY JACK TOM BOB ADAM DAM
 
 
 
 
题解:
  好久没有写题了,代码能力都不行了·······注意splay处理区间问题一般要加两个哨兵(烧饼)节点,还有这道题n貌似可以到250000(我也不清楚具体多少,反正200000会挂),更坑爹的是Score可以爆int,坑坑坑
code:
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<cassert>
  7 using namespace std;
  8 typedef long long int64;
  9 char ch; bool ok;
 10 void read(int &x){
 11     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
 12     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
 13     if (ok) x=-x;
 14 }
 15 void read(int64 &x){
 16     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
 17     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
 18     if (ok) x=-x;
 19 }
 20 const int maxn=600005;
 21 const int64 inf=9223372036854775807LL;
 22 int q,idx,list[maxn];
 23 int64 x;
 24 char op,tmp[12],name[maxn][12];
 25 struct Hash{
 26     static const int base1=97;
 27     static const int mod1=99997;
 28     static const int base2=103;
 29     static const int mod2=3777777;
 30     int tot,now[mod1],pre[maxn],key[maxn];
 31     void init(){tot=0;memset(now,0,sizeof(now));}
 32     int find(){
 33         int u=0,k=0;
 34         for (int i=1;tmp[i];i++) u=(u*base1+tmp[i])%mod1,k=(k*base2+tmp[i])%mod2;
 35         for (int p=now[u];p;p=pre[p]) if (key[p]==k) return p;
 36         pre[++tot]=now[u],now[u]=tot,key[tot]=k;
 37         for (int i=1;tmp[i];i++) name[tot][i]=tmp[i];
 38         return tot;
 39     }
 40 }data;
 41 struct Splay{
 42     int tot,root,son[maxn][2],fa[maxn],siz[maxn],pos[maxn];
 43     int64 val[maxn];
 44     int which(int x){return son[fa[x]][1]==x;}
 45     void updata(int x){siz[x]=siz[son[x][0]]+1+siz[son[x][1]];}
 46     void rotate(int x){
 47         int y=fa[x],z=fa[y],d=which(x),dd=which(y);
 48         son[y][d]=son[x][d^1],fa[son[x][d^1]]=y,fa[x]=z;
 49         if (z) son[z][dd]=x;
 50         son[x][d^1]=y,fa[y]=x,updata(y),updata(x);    
 51     }
 52     void splay(int x){
 53         while (fa[x]){
 54             if (!fa[fa[x]]) rotate(x);
 55             else if (which(fa[x])==which(x)) rotate(fa[x]),rotate(x);
 56             else rotate(x),rotate(x);
 57         }
 58         root=x;
 59     }
 60     void init(){
 61         memset(siz,0,sizeof(siz)),memset(pos,0,sizeof(pos));
 62         data.init();
 63         root=q+1;
 64         siz[q+1]=2,fa[q+1]=0,son[q+1][0]=0,son[q+1][1]=q+2,val[q+1]=inf;
 65         siz[q+2]=1,fa[q+2]=q+1,son[q+2][0]=son[q+2][1]=0,val[q+2]=-inf;
 66     }
 67     int find_left(int x){
 68         for (;son[x][0];x=son[x][0]);
 69         return x;    
 70     }
 71     void del(int x){
 72         splay(x);
 73         int y=find_left(son[x][1]);
 74         fa[son[x][0]]=fa[son[x][1]]=0;
 75         splay(y),son[y][0]=son[x][0],fa[son[x][0]]=y,updata(y);
 76     }
 77     void insert(int x){
 78         int f,t;
 79         for (f=t=root;t;f=t,t=son[t][val[x]<=val[t]]);
 80         assert(f!=0);
 81         fa[x]=f,son[f][val[x]<=val[f]]=x,splay(x);
 82     }
 83     void push(int64 v){
 84         int id=data.find();
 85         if (pos[id]==0) pos[id]=++tot;
 86         else del(pos[id]);
 87         val[id]=v,siz[id]=1,fa[id]=son[id][0]=son[id][1]=0,insert(pos[id]);
 88     }
 89     int find(int x,int rank){
 90         if (siz[son[x][0]]>=rank) return find(son[x][0],rank);
 91         if (siz[son[x][0]]+1==rank) return x;
 92         return find(son[x][1],rank-siz[son[x][0]]-1);
 93     }
 94     void answer(int x,int rest){
 95         if (rest==0||x==0) return;
 96         answer(son[x][0],rest);
 97         if (siz[son[x][0]]<rest){
 98             list[++idx]=x;
 99             answer(son[x][1],rest-siz[son[x][0]]-1);
100         }
101     }
102     void query_list(int rank){
103         int id=find(root,rank+1);
104         splay(id);
105         list[idx=1]=id;
106         answer(son[id][1],9);
107         if (!name[list[idx]][1]) idx--;
108         for (int i=1;i<idx;i++) printf("%s ",name[list[i]]+1);
109         printf("%s\n",name[list[idx]]+1);
110     }
111     void query_rank(){
112         int id=data.find();
113         splay(id),printf("%d\n",siz[son[id][0]]);
114     }
115 }T;
116 int main(){
117     for (read(q),T.init();q;q--){
118         for (op=getchar();op!='+'&&op!='?';op=getchar());
119         if (op=='+') scanf("%s",tmp+1),read(x),T.push(x);
120         else if (op=='?'){
121             scanf("%s",tmp+1);
122             if (isdigit(tmp[1])){
123                 x=0;
124                 for (int i=1;tmp[i];i++) x=x*10+tmp[i]-'0';
125                 T.query_list(x);
126             }
127             else T.query_rank();
128         }
129     }
130     return 0;
131 }

 

posted @ 2017-06-12 20:46 chenyushuo 阅读(...) 评论(...) 编辑 收藏