hdu 3436 Queuejumpers(Splay Tree)

acm.hdu.edu.cn/showproblem.php?pid=3436

  中等难度的数据结构题,不过数据范围大,所以要hash操作过的数列。1y~

  题意就像题目一样,模拟一队人,其中有人插队,询问某个时刻,第x个人的编号或编号为x的人的位置。

代码如下:

View Code
  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <set>
  6 
  7 using namespace std;
  8 
  9 struct Node {
 10     int l, r;
 11     int cnt;
 12     Node *c[2], *p;
 13 
 14     Node (int _cnt = 0, int _l = 0, int _r = -1) {
 15         l = _l;
 16         r = _r;
 17         cnt = _cnt;
 18         c[0] = c[1] = p = NULL;
 19     }
 20 } *Null, *Root, *Head;
 21 
 22 void up(Node *rt) {
 23     rt->cnt = rt->c[0]->cnt + rt->c[1]->cnt + (rt->r - rt->l + 1);
 24 }
 25 
 26 void rotate(Node *x, bool right) {
 27     Node *y = x->p;
 28 
 29     y->c[!right] = x->c[right];
 30     if (x->c[right] != Null) {
 31         x->c[right]->p = y;
 32     }
 33     x->p = y->p;
 34     if (y->p != Null) {
 35         if (y->p->c[0] == y) {
 36             y->p->c[0] = x;
 37         } else {
 38             y->p->c[1] = x;
 39         }
 40     }
 41     x->c[right] = y;
 42     y->p = x;
 43     up(y);
 44 
 45     if (Root == y) Root = x;
 46 }
 47 
 48 void splay(Node *x, Node *f) {
 49     while (x->p != f) {
 50         if (x->p->p == f) {
 51             if (x->p->c[0] == x) rotate(x, 1);
 52             else rotate(x, 0);
 53         } else {
 54             Node *y = x->p, *z = y->p;
 55 
 56             if (z->c[0] == y) {
 57                 if (y->c[0] == x) {
 58                     rotate(y, 1);
 59                     rotate(x, 1);
 60                 } else {
 61                     rotate(x, 0);
 62                     rotate(x, 1);
 63                 }
 64             } else {
 65                 if (y->c[0] == x) {
 66                     rotate(x, 1);
 67                     rotate(x, 0);
 68                 } else {
 69                     rotate(y, 0);
 70                     rotate(x, 0);
 71                 }
 72             }
 73         }
 74     }
 75 
 76     up(x);
 77 }
 78 
 79 const int inf = 0x7f7f7f7f;
 80 
 81 void initSplay() {
 82     Null = new Node();
 83     Root = Head = new Node(1, 0, 0);
 84 
 85     Root->p = Root->c[0] = Null;
 86     Root->c[1] = new Node(1, inf, inf);
 87     Root->c[1]->p = Root;
 88     Root->c[1]->c[0] = Root->c[1]->c[1] = Null;
 89     up(Root);
 90 }
 91 
 92 void in_tra(Node *rt) {
 93     if (rt == Null) {
 94         return ;
 95     }
 96     in_tra(rt->c[0]);
 97     printf("%d %d %d %d %d %d %d\n", rt->l, rt->r, rt->cnt, rt, rt->p, rt->c[0], rt->c[1]);
 98     in_tra(rt->c[1]);
 99 }
100 
101 const int maxn = 100005;
102 const int HASH = 0x55555555;
103 const int hashMod = 400009;
104 
105 char op[maxn][6];
106 int num[maxn], hash[hashMod], hashPos[hashMod];
107 
108 void initHash() {
109     memset(hashPos, 0, sizeof(hashPos));
110 }
111 
112 void insHash(int x, int pos) {
113     int p = (x ^ HASH) % hashMod;
114 
115     while (hash[p] != x && hashPos[p]) {
116         p++;
117         if (p >= hashMod) p -= hashMod;
118     }
119 
120     hash[p] = x;
121     hashPos[p] = pos;
122 }
123 
124 int getHash(int x) {
125     int p = (x ^ HASH) % hashMod;
126 
127     while (hash[p] != x && hashPos[p]) {
128         p++;
129         if (p >= hashMod) p -= hashMod;
130     }
131 
132     return hashPos[p];
133 }
134 
135 Node *rec[maxn << 1];
136 
137 void insSplay(Node *x) {
138     x->c[1] = Root->c[1];
139     Root->c[1]->p = x;
140     Root->c[1] = x;
141     x->p = Root;
142     x->c[0] = Null;
143 
144     splay(x, Null);
145 }
146 
147 void build(int n, int m) {
148     set<int> used;
149 
150     initSplay();
151     used.clear();
152     for (int i = 0; i < m; i++) {
153         scanf("%s%d", op[i], &num[i]);
154         if (op[i][0] == 'T' || op[i][0] == 'Q') {
155             used.insert(num[i]);
156         }
157     }
158 
159     int last = 0, cnt = 0;
160 
161     for (set<int>::iterator si = used.begin(); si != used.end(); si++) {
162 //        printf("%d\n", *si);
163         if (last + 1 < *si) {
164             rec[++cnt] = new Node(1, last + 1, *si - 1);
165 //            printf("add %d %d\n", last + 1, *si - 1);
166             insSplay(rec[cnt]);
167         }
168         rec[++cnt] = new Node(1, *si, *si);
169 //        printf("add %d\n", *si);
170         insSplay(rec[cnt]);
171 
172         insHash(*si, cnt);
173         last = *si;
174     }
175     if (last < n) {
176         rec[++cnt] = new Node(1, last + 1, n);
177 //        printf("add %d %d\n", last + 1, n);
178         insSplay(rec[cnt]);
179     }
180 
181 //    printf("cnt %d\n", cnt);
182 //    puts("built!");
183 }
184 
185 int getPos(int x) {
186     Node *rt = rec[getHash(x)];
187 
188     splay(rt, Null);
189 
190     return rt->c[0]->cnt;
191 }
192 
193 int getPer(int pos) {
194     Node *p = Root;
195 
196     pos++;
197     while (true) {
198         int cnt = p->c[0]->cnt;
199 
200         if (cnt + 1 <= pos && pos <= cnt + (p->r - p->l + 1)) {
201             pos -= cnt;
202 
203             return p->l + pos - 1;
204         } else if (pos <= cnt) {
205 //            puts("left");
206             p = p->c[0];
207         } else {
208 //            puts("right");
209             pos -= cnt + (p->r - p->l + 1);
210             p = p->c[1];
211         }
212     }
213 }
214 
215 Node *preNode(Node *x) {
216     splay(x, Null);
217     x = x->c[0];
218     while (x->c[1] != Null) x = x->c[1];
219 
220     return x;
221 }
222 
223 Node *postNode(Node *x) {
224     splay(x, Null);
225     x = x->c[1];
226     while (x->c[0] != Null) x = x->c[0];
227 
228     return x;
229 }
230 
231 void Top(int x) {
232     x = getHash(x);
233 //    printf("x %d\n", x);
234 
235     Node *pl = preNode(rec[x]);
236     Node *pr = postNode(rec[x]);
237 
238     splay(pl, Null);
239     splay(pr, pl);
240 
241     // cut node
242     Node *tmp = pr->c[0];
243     pr->c[0] = Null;
244     splay(pr, Null);
245     // top node
246     splay(Head, Null);
247     insSplay(tmp);
248 }
249 
250 void process(int m) {
251     for (int i = 0; i < m; i++) {
252         switch (op[i][0]) {
253             case 'T':
254 //                puts("Top");
255                 Top(num[i]);
256                 break;
257             case 'Q':
258 //                puts("Query");
259                 printf("%d\n", getPos(num[i]));
260                 break;
261             case 'R':
262 //                puts("Rank");
263                 printf("%d\n", getPer(num[i]));
264                 break;
265         }
266     }
267 }
268 
269 int main() {
270     int T;
271 
272 //    freopen("in", "r", stdin);
273     scanf("%d", &T);
274     for (int i = 1; i <= T; i++) {
275         int n, m;
276 
277         scanf("%d%d", &n, &m);
278         build(n, m);
279         printf("Case %d:\n", i);
280         process(m);
281     }
282 
283     return 0;
284 }

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3436_Lyon.html