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的排名
+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
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 }