BYRBT

BZOJ 1056——HAOI 2008 排名系统

http://61.187.179.132/JudgeOnline/problem.php?id=1056

 

Description

排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。

Input

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

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
4





HINT

20%数据满足N<=100
100%数据满足N<=250000

Source

 

题解:

  赤裸裸的数据结构题啊,乱维护一下hash值再怎么乱搞一下就行了,但是我的splay肿么调都调不过,始终T………………于是改写treap了,比splay快多了,再也不相信splay了……………………

 

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<map>
  5 
  6 using namespace std;
  7 
  8 #define ull unsigned long long
  9 
 10 const int maxn=220010;
 11 const ull seed=99991;
 12 
 13 int n,cnt,nowcnt,l;
 14 
 15 char s[13],ss[maxn][13];
 16 
 17 struct rec
 18 {
 19     int v,t;
 20     rec(){}
 21     rec(int a,int b)
 22     {
 23         v=a;t=b;
 24     }
 25     bool operator<(const rec &a)const
 26     {
 27         if (v==a.v) return t>a.t;
 28         else return v<a.v;
 29     }
 30     bool operator==(const rec &a)const
 31     {
 32         return v==a.v && t==a.t;
 33     }
 34 }wmt[maxn];
 35 
 36 map<ull , int> ma;
 37 
 38 struct node
 39 {
 40     int l,r,size,id,fix;
 41     rec v;
 42 };
 43 
 44 struct treap
 45 {
 46     node z[maxn];
 47     int osize,size,root;
 48     treap()
 49     {
 50         osize=size=root=0;
 51     }
 52     void update(int now)
 53     {
 54         z[now].size=z[z[now].l].size+z[z[now].r].size+1;
 55     }
 56     void rot_r(int &now)
 57     {
 58         int a=z[now].l;
 59         z[now].l=z[a].r;
 60         z[a].r=now;
 61         update(now);
 62         update(a);
 63         now=a;
 64     }
 65     void rot_l(int &now)
 66     {
 67         int a=z[now].r;
 68         z[now].r=z[a].l;
 69         z[a].l=now;
 70         update(now);
 71         update(a);
 72         now=a;
 73     }
 74     void insert(int &now,rec v)
 75     {
 76         if (now==0)
 77         {
 78             osize++;
 79             size++;
 80             now=size;
 81             z[now].l=z[now].r=0;
 82             z[now].v=v;
 83             z[now].fix=rand();
 84             z[now].id=nowcnt;
 85             z[now].size=1;
 86             return;
 87         }
 88         if (z[now].v<v)
 89         {
 90             insert(z[now].l,v);
 91             update(now);
 92             if (z[z[now].l].fix>z[now].fix) rot_r(now);
 93         }
 94         else
 95         {
 96             insert(z[now].r,v);
 97             update(now);
 98             if (z[z[now].r].fix>z[now].fix) rot_l(now);
 99         }
100     }
101     void del(int &now,rec v)
102     {
103         if (now==0) return;
104         if (z[now].v<v) del(z[now].l,v);
105         else
106         {
107             if (v<z[now].v) del(z[now].r,v);
108             else
109             {
110                 if ((z[now].l==0) && (z[now].r==0))
111                 {
112                     osize--;
113                     now=0;
114                     return;
115                 }
116                 if (z[now].l==0)
117                 {
118                     osize--;
119                     now=z[now].r;
120                     return;
121                 }
122                 if (z[now].r==0)
123                 {
124                     osize--;
125                     now=z[now].l;
126                     return;
127                 }
128                 if (z[z[now].l].fix<z[z[now].r].fix)
129                 {
130                     rot_l(now);
131                     del(z[now].l,v);
132                     update(now);
133                 }
134                 else
135                 {
136                     rot_r(now);
137                     del(z[now].r,v);
138                     update(now);
139                 }
140             }
141         }
142         update(now);
143     }
144     int rank(rec now)
145     {
146         int p=root,ans=0;
147         while (p)
148         {
149             if (z[p].v==now) return ans+z[z[p].l].size+1;
150             if (now<z[p].v) ans+=z[z[p].l].size+1,p=z[p].r;
151             else p=z[p].l;
152         }
153         return 0;
154     }
155     void dfs(int p)
156     {
157         if (cnt>=10) return;
158         if (z[p].l) dfs(z[p].l);
159         if (cnt>=10) return;
160         printf("%s ",ss[z[p].id]);
161         cnt++;
162         if (cnt>=10) return;
163         if (z[p].r) dfs(z[p].r);
164     }
165     void find(int v)
166     {
167         int p=root;
168         while (v)
169         {
170             if (z[z[p].l].size+1==v) break;
171             if (v>z[z[p].l].size) v-=z[z[p].l].size+1,p=z[p].r;
172             else p=z[p].l;
173         }
174         printf("%s",ss[z[p].id]);
175     }
176 }tree;
177 
178 ull hash()
179 {
180     int l=strlen(s);
181     ull ans=0;
182     for (int a=0;a<l;a++)
183         ans=(ans*seed+s[a]-'A'+1);
184     return ans;
185 }
186 
187 int main()
188 {
189     freopen("rank.in","r",stdin);
190     freopen("rank.out","w",stdout);
191 
192     scanf("%d",&n);
193     char c='!';
194     while (c!='\n' && c!='\r')
195         scanf("%c",&c);
196     int v,nowid,nowl;
197     ull ha;
198     for (int a=1;a<=n;a++)
199     {
200         scanf("%c",&c);
201         if (c=='+')
202         {
203             scanf("%s",s);
204             scanf("%d",&v);
205             ha=hash();
206             nowid=ma[ha];
207             if (nowid==0)
208             {
209                 l++;
210                 wmt[l]=rec(v,a);
211                 nowcnt=l;
212                 for (int b=0;b<=12;b++)
213                     ss[l][b]=s[b];
214                 ma[ha]=l;
215             }
216             else 
217             {
218                 nowcnt=nowid;
219                 tree.del(tree.root,wmt[nowcnt]);
220                 wmt[nowid]=rec(v,a);
221             }
222             tree.insert(tree.root,rec(v,a));
223         }
224         else
225         {
226             scanf("%s",s);
227             if (s[0]>='0' && s[0]<='9')
228             {
229                 v=0;
230                 nowl=strlen(s);
231                 for (int b=0;b<nowl;b++)
232                     v=v*10+s[b]-'0';
233                 int maxsize=min(tree.osize,v+9);
234                 for (int b=v;b<=maxsize;b++)
235                 {
236                     tree.find(b);
237                     if (b==maxsize) printf("\n");
238                     else printf(" ");
239                 }
240             }
241             else 
242             {
243                 ha=hash();
244                 printf("%d\n",tree.rank(wmt[ma[ha]]));
245             }
246         }
247         c='!';
248         while (~scanf("%c",&c))
249             if (c=='\n' || c=='\r') break;
250     }
251 
252     return 0;
253 }
posted @ 2012-09-24 10:57  zhonghaoxi  阅读(427)  评论(0编辑  收藏  举报
BYRBT