hdu 3436 Queue-jumpers(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