Splay Tree (POJ 3580 & UVA 12356 & HDU 1890)
最近几天熟悉着用Linux,所以做题的量少了下来。这几天新学习了Splay Tree这种数据结构,于是在看懂了Splay操作以后就找了几道题来练手,除了UVA那题是1y顺利通过的,其他两题都出现了各种不同的错误,不过最终还是通过了!
POJ 3580是我入手Splay Tree的第一道题,这道题需要的操作包括:
1.区间增加相同的数
2.区间反转
3.区间滚动
4.插入一个数
5.删除一个数
6.查询一个区间内的最小值
我的Splay操作是学习《运用伸展树解决数列维护问题》的论文的,里面教的Splay和Rotate操作包括单纯的和加上更新操作两种。知道了Splay操作以后,延迟操作跟线段树的是一样的,所以不必重新再学。刚学会Splay操作的时候,还不太懂Splay的原理,所以在写insert和delete的时候各种囧态浮现。。。囧!刚开始的时候,我的insert和delete还是很笨重的写了一大串其他平衡树用的insert和delete的方法,出现各种bug以后,我忽而醒觉了,原来Everything is Splay! 这句不知道在哪里听过的话是那么的正确。用Splay Tree就是要将各种操作简化,insert或者delete的时候,只要把要insert和delete的位置Splay出来,剩下要做的事就相当简单了!
POJ 3580: poj.org/problem?id=3580
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #define prog 1 2 3 #if prog == 1 4 5 #include <cstdio> 6 #include <cstdlib> 7 #include <cstring> 8 #include <cassert> 9 #include <algorithm> 10 11 using namespace std; 12 13 const int inf = 0x7f7f7f7f; 14 15 struct Node { 16 int lateAdd, Min, Data, cnt; 17 bool Rev; 18 Node *c[2], *p; // 0 for left child, while 1 for right child 19 20 Node(int _Data = inf, int _cnt = 0) { 21 Rev = false; 22 Min = Data = _Data; 23 lateAdd = 0; 24 cnt = _cnt; 25 c[0] = c[1] = p = NULL; 26 } 27 } *Null, *Root, *Head, *Tail; 28 29 void up(Node *_x) { 30 Node *nl = _x->c[0], *nr = _x->c[1]; 31 32 _x->Min = min(min(nl->Min, nr->Min), _x->Data); 33 _x->cnt = nl->cnt + nr->cnt + 1; 34 } 35 36 void down(Node *_x) { 37 Node *nl = _x->c[0], *nr = _x->c[1]; 38 39 if (_x->Rev) { 40 if (nl != Null) { 41 swap(nl->c[0], nl->c[1]); 42 nl->Rev = !nl->Rev; 43 } 44 if (nr != Null) { 45 swap(nr->c[0], nr->c[1]); 46 nr->Rev = !nr->Rev; 47 } 48 _x->Rev = false; 49 } 50 if (_x->lateAdd) { 51 int late = _x->lateAdd; 52 53 if (nl != Null) { 54 nl->Min += late; 55 nl->Data += late; 56 nl->lateAdd += late; 57 } 58 if (nr != Null) { 59 nr->Min += late; 60 nr->Data += late; 61 nr->lateAdd += late; 62 } 63 _x->lateAdd = 0; 64 } 65 } 66 67 void traverse(Node *rt) { 68 if (rt == Null) { 69 return ; 70 } 71 down(rt); 72 printf("rt %d p %d ls %d rs %d data %d min %d cnt %d\n", rt, rt->p, rt->c[0], rt->c[1], rt->Data, rt->Min, rt->cnt); 73 traverse(rt->c[0]); 74 traverse(rt->c[1]); 75 } 76 77 void in_tra(Node *rt) { 78 if (rt == Null) { 79 return ; 80 } 81 down(rt); 82 in_tra(rt->c[0]); 83 if (rt ->Data != inf) printf("%d ", rt->Data); 84 in_tra(rt->c[1]); 85 up(rt); 86 } 87 88 void Rotate(Node *_x, bool right) { // false for left rotate, while true for right rotate 89 Node *_y = _x->p; 90 bool left = !right; 91 92 down(_y); 93 down(_x); 94 _y->c[left] = _x->c[right]; 95 96 if (_x->c[right] != Null) _x->c[right]->p = _y; 97 _x->p = _y->p; 98 if (_y->p != Null) { 99 if (_y->p->c[0] == _y) { 100 _y->p->c[0] = _x; 101 } else { 102 _y->p->c[1] = _x; 103 } 104 } 105 106 _x->c[right] = _y; 107 _y->p = _x; 108 if (_y == Root) Root = _x; 109 110 up(_y); 111 } 112 113 void Splay(Node *_x, Node *_f) {// splay _x to the node under _f 114 down(_x); 115 while (_x->p != _f) { 116 if (_x->p->p == _f) { 117 if (_x->p->c[0] == _x) { 118 Rotate(_x, 1); 119 } else { 120 Rotate(_x, 0); 121 } 122 } else { 123 Node *_y = _x->p, *_z = _y->p; 124 125 if (_z->c[0] == _y) { 126 if (_y->c[0] == _x) { 127 Rotate(_y, 1); 128 Rotate(_x, 1); 129 } else { 130 Rotate(_x, 0); 131 Rotate(_x, 1); 132 } 133 } else { 134 if (_y->c[0] == _x) { 135 Rotate(_x, 1); 136 Rotate(_x, 0); 137 } else { 138 Rotate(_y, 0); 139 Rotate(_x, 0); 140 } 141 } 142 } 143 } 144 145 up(_x); 146 } 147 148 Node *getPos(int pos) { 149 Node *p = Root; 150 151 // find position 152 pos++; 153 while (true) { 154 down(p); 155 156 int cnt = p->c[0]->cnt; 157 158 if (pos == cnt + 1) { 159 break; 160 } else if (pos <= cnt) { 161 p = p->c[0]; 162 } else { 163 pos -= cnt + 1; 164 p = p->c[1]; 165 } 166 } 167 168 return p; 169 } 170 171 void insPos(int elem, int pos) { 172 Node *pl = getPos(pos), *pr = getPos(pos + 1); 173 Node *tmp = new Node(elem, 1); 174 175 // insert node 176 Splay(pl, Null); 177 Splay(pr, pl); 178 pr->c[0] = tmp; 179 tmp->p = pr; 180 tmp->c[0] = tmp->c[1] = Null; 181 182 Splay(tmp, Null); 183 } 184 185 void delPos(int pos) { 186 Node *pl = getPos(pos - 1), *pr = getPos(pos + 1); 187 Node *p; 188 189 Splay(pl, Null); 190 Splay(pr, pl); 191 p = pr->c[0]; 192 pr->c[0] = Null; 193 194 delete p; 195 Splay(pr, Null); 196 } 197 198 void init() { 199 Null = new Node(); 200 Head = Root = new Node(inf, 2); 201 Tail = new Node(inf, 1); 202 203 Root->c[1] = Tail; 204 Root->c[0] = Root->p = Null; 205 Tail->p = Root; 206 Tail->c[0] = Tail->c[1] = Null; 207 } 208 209 void input(int n) { 210 int x; 211 212 for (int i = 0; i < n; i++) { 213 scanf("%d", &x); 214 insPos(x, i); 215 } 216 } 217 218 void reverse(int l, int r) { 219 if (l == r) return ; 220 Node *pl = getPos(l - 1), *pr = getPos(r + 1); 221 222 // get segment 223 Splay(pl, Null); 224 Splay(pr, pl); 225 226 pr = pr->c[0]; 227 swap(pr->c[0], pr->c[1]); 228 pr->Rev = true; 229 230 Splay(pr, Null); 231 } 232 233 void revolve(int l, int r, int t) { 234 t %= (r - l + 1); 235 if (l == r || t == 0) return ; 236 237 Node *pl = getPos(r - t), *pr = getPos(r + 1); 238 239 // printf("%d %d %d %d %d\n", pl, pr, l, r, t); 240 241 // get segment 242 Splay(pl, Null); 243 Splay(pr, pl); 244 245 // cut down segment 246 Node *tmp = pr->c[0]; 247 248 pr->c[0] = Null; 249 Splay(pr, Null); 250 251 // insert segment 252 pl = getPos(l - 1); 253 pr = getPos(l); 254 Splay(pl, Null); 255 Splay(pr, pl); 256 257 pr->c[0] = tmp; 258 tmp->p = pr; 259 Splay(tmp, Null); 260 } 261 262 void add(int l, int r, int d) { 263 Node *pl = getPos(l - 1), *pr = getPos(r + 1); 264 265 // printf("%d %d %d %d\n", pl, pr, l, r); 266 Splay(pl, Null); 267 Splay(pr, pl); 268 269 pr = pr->c[0]; 270 down(pr); 271 pr->lateAdd += d; 272 pr->Data += d; 273 pr->Min += d; 274 Splay(pr, Null); 275 } 276 277 int getMin(int l, int r) { 278 Node *pl = getPos(l - 1), *pr = getPos(r + 1); 279 280 Splay(pl, Null); 281 Splay(pr, pl); 282 pr = pr->c[0]; 283 down(pr); 284 285 return pr->Min; 286 } 287 288 int main() { 289 int n; 290 // int cnt = 0; 291 292 // freopen("in", "r", stdin); 293 // freopen("out", "w", stdout); 294 295 while (~scanf("%d", &n)) { 296 // printf("cnt %d\n", ++cnt); 297 init(); 298 input(n); 299 // puts("Input success!"); 300 // puts("~~~"); 301 // traverse(Root); 302 // puts("!!!"); 303 scanf("%d", &n); 304 // in_tra(Root); 305 // printf("~~~cnt %d\n", Root->cnt - 2); 306 for (int i = 1; i <= n; i++) { 307 char buf[10]; 308 int l, r, d ; 309 310 scanf("%s", buf); 311 if (!strcmp(buf, "ADD")) { 312 scanf("%d%d%d", &l, &r, &d); 313 if (l > r) swap(l, r); 314 add(l, r, d); 315 } else if (!strcmp(buf, "REVERSE")) { 316 scanf("%d%d", &l, &r); 317 if (l > r) swap(l, r); 318 reverse(l, r); 319 } else if (!strcmp(buf, "REVOLVE")) { 320 scanf("%d%d%d", &l, &r, &d); 321 if (l > r) swap(l, r); 322 revolve(l, r, d); 323 } else if (!strcmp(buf, "INSERT")) { 324 scanf("%d%d", &l, &r); 325 insPos(r, l); 326 } else if (!strcmp(buf, "DELETE")) { 327 scanf("%d", &l); 328 delPos(l); 329 } else { 330 scanf("%d%d", &l, &r); 331 if (l > r) swap(l, r); 332 printf("%d\n", getMin(l, r)); 333 } 334 335 // printf("op %d %s\n", i, buf); 336 // in_tra(Root); 337 // printf("~~~cnt %d\n", Root->cnt - 2); 338 339 // puts("~~~~~~~~~~~~~"); 340 // traverse(Root); 341 // puts("!!!!!!!!!!!!!"); 342 } 343 } 344 345 return 0; 346 } 347 348 #endif 349 350 #if prog == 2 351 352 #include <cstdio> 353 #include <cstring> 354 #include <algorithm> 355 356 using namespace std; 357 358 const int maxn = 10000; 359 int a[maxn], ttLen; 360 361 void input(int n) { 362 ttLen = n; 363 for (int i = 1; i <= n; i++) { 364 scanf("%d", &a[i]); 365 } 366 } 367 368 void add(int l, int r, int d) { 369 for (int i = l; i <= r; i++) { 370 a[i] += d; 371 } 372 } 373 374 void revolve(int l, int r, int t) { 375 t %= (r - l + 1); 376 if (r == l || t == 0) return ; 377 378 int buf[maxn]; 379 380 for (int i = l; i <= r; i++) { 381 buf[i - l] = a[i]; 382 } 383 for (int i = 0; i <= r - l; i++) { 384 a[(i + t) % (r - l + 1) + l] = buf[i]; 385 } 386 } 387 388 void insPos(int elem, int pos) { 389 int p = ttLen; 390 391 while (p > pos) { 392 a[p + 1] = a[p]; 393 p--; 394 } 395 a[pos + 1] = elem; 396 ttLen++; 397 } 398 399 void delPos(int pos) { 400 int p = pos; 401 402 while (p < ttLen) { 403 a[p] = a[p + 1]; 404 p++; 405 } 406 ttLen--; 407 } 408 409 int getMin(int l, int r) { 410 int ret = 0x7f7f7f7f; 411 412 for (int i = l; i <= r; i++) { 413 ret = min(ret, a[i]); 414 } 415 416 return ret; 417 } 418 419 int main() { 420 int n; 421 422 freopen("in", "r", stdin); 423 freopen("cmp", "w", stdout); 424 425 while (~scanf("%d", &n)) { 426 input(n); 427 428 scanf("%d", &n); 429 for (int i = 1; i <= ttLen; i++) printf("%d ", a[i]); 430 printf("~~~cnt %d\n", ttLen); 431 for (int i = 1; i <= n; i++) { 432 char buf[10]; 433 int l, r, d ; 434 435 scanf("%s", buf); 436 if (!strcmp(buf, "ADD")) { 437 scanf("%d%d%d", &l, &r, &d); 438 if (l > r) swap(l, r); 439 add(l, r, d); 440 } else if (!strcmp(buf, "REVERSE")) { 441 scanf("%d%d", &l, &r); 442 if (l > r) swap(l, r); 443 reverse(a + l, a + r + 1); 444 } else if (!strcmp(buf, "REVOLVE")) { 445 scanf("%d%d%d", &l, &r, &d); 446 if (l > r) swap(l, r); 447 revolve(l, r, d); 448 } else if (!strcmp(buf, "INSERT")) { 449 scanf("%d%d", &l, &r); 450 insPos(r, l); 451 } else if (!strcmp(buf, "DELETE")) { 452 scanf("%d", &l); 453 delPos(l); 454 } else { 455 scanf("%d%d", &l, &r); 456 if (l > r) swap(l, r); 457 printf("%d\n", getMin(l, r)); 458 } 459 460 // printf("op %d %s\n", i, buf); 461 // for (int j = 1; j <= ttLen; j++) printf("%d ", a[j]); 462 // printf("~~~cnt %d\n", ttLen); 463 464 } 465 } 466 467 return 0; 468 } 469 470 #endif
下面这是昨晚训练的一道题,刚开始的时候我直接就想到了Segment Tree,可是想到这题用Segment Tree解决的代码难度相对用Splay Tree会大不少,所以我就想到了用昨天懂的Splay Tree来完成,虽然中间出现一点小问题,不过最后还是1y通过了!
题意是初始化一个1到n的序列,每个操作将删除指定的区间,并且返回区间两端最接近的未被删除的点的位置,如果没有就返回星号。用Splay Tree方便就是方便在删除区间的同时就找到了要输出的两个值。查找端点的时候,先找到最接近区间端点的值的结点,然后利用Splay操作,把该结点旋转至根,这样可以相当方便的找到前驱和后继。删除区间就是删除被夹逼出来的一个子树。这题给了一秒的时间,刚开始评估复杂度的时候因为Splay操作常数大,觉得可能会超时,结果不到500ms就得到结果了!
UVA 12356: uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3778
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <stack> 6 #include <vector> 7 #include <cmath> 8 9 using namespace std; 10 int inf = 0x7f7f7f7f; 11 12 struct Node { 13 int key, cnt; 14 int p, c[2]; 15 16 void init(int _key, int _cnt) { 17 key = _key; 18 cnt = _cnt; 19 p = c[0] = c[1] = 0; 20 } 21 } node[100010]; 22 int Null, Root, cntNode; 23 24 void up(int rt) { 25 node[rt].cnt = node[node[rt].c[0]].cnt + node[node[rt].c[1]].cnt + 1; 26 } 27 28 void rotate(int x, bool right) { 29 int y = node[x].p; 30 bool left = !right; 31 32 node[y].c[left] = node[x].c[right]; 33 if (node[x].c[right] != Null) node[node[x].c[right]].p = y; 34 node[x].p = node[y].p; 35 if (node[y].p != Null) { 36 if (node[node[y].p].c[false] == y) node[node[y].p].c[false] = x; 37 else node[node[y].p].c[true] = x; 38 } 39 node[x].c[right] = y; 40 node[y].p = x; 41 42 if (y == Root) Root = x; 43 up(x); 44 } 45 46 void splay(int x, int f) { 47 while (node[x].p != f) { 48 if (node[node[x].p].p == f) { 49 if (node[node[x].p].c[0] == x) { 50 rotate(x, true); 51 } else { 52 rotate(x, false); 53 } 54 } else { 55 int y = node[x].p, z = node[y].p; 56 57 if (node[z].c[false] == y) { 58 if (node[y].c[false] == x) { 59 rotate(y, true); 60 rotate(x, true); 61 } else { 62 rotate(x, false); 63 rotate(x, true); 64 } 65 } else { 66 if (node[y].c[false] == x) { 67 rotate(x, true); 68 rotate(x, false); 69 } else { 70 rotate(y, false); 71 rotate(x, false); 72 } 73 } 74 } 75 } 76 up(x); 77 } 78 79 void init() { 80 Null = 0; 81 node[Null].init(inf, 0); 82 Root = cntNode = 1; 83 84 node[Root].init(-inf, 1); 85 cntNode++; 86 node[Root].c[1] = cntNode; 87 node[cntNode].init(inf, 1); 88 node[cntNode].p = Root; 89 } 90 91 int find(int key, bool right) { 92 int p = Root; 93 94 while (true) { 95 if (node[p].key == key) break; 96 else if (node[p].key < key) { 97 if (node[p].c[1] == Null) break; 98 p = node[p].c[1]; 99 } else { 100 if (node[p].c[0] == Null) break; 101 p = node[p].c[0]; 102 } 103 } 104 if (right) { 105 if (node[p].key <= key) { 106 splay(p, Null); 107 while (node[p].key <= key) p = node[p].c[1]; 108 while (node[p].c[0] != Null && node[node[p].c[0]].key >= key) p = node[p].c[0]; 109 } 110 return p; 111 } else { 112 if (node[p].key >= key) { 113 splay(p, Null); 114 while (node[p].key >= key) p = node[p].c[0]; 115 while (node[p].c[1] != Null && node[node[p].c[1]].key <= key) p = node[p].c[1]; 116 } 117 return p; 118 } 119 } 120 121 void delSeg(int &l, int &r){ 122 l = find(l, false); 123 // puts("~~~"); 124 r = find(r, true); 125 // puts("!!!"); 126 // printf("%d %d\n", l, r); 127 // printf("%d %d\n", node[l].key, node[r].key); 128 splay(l, Null); 129 splay(r, l); 130 node[r].c[0] = Null; 131 } 132 133 void build(int n) { 134 init(); 135 for (int i = 1; i <= n; i++) { 136 cntNode++; 137 node[cntNode].init(i, 1); 138 node[cntNode].c[1] = node[Root].c[1]; 139 node[node[Root].c[1]].p = cntNode; 140 node[Root].c[1] = cntNode; 141 node[cntNode].p = Root; 142 143 splay(cntNode, Null); 144 } 145 } 146 147 void in_tra(int rt) { 148 if (rt == Null) return ; 149 in_tra(node[rt].c[0]); 150 printf("%d ", node[rt].key); 151 in_tra(node[rt].c[1]); 152 } 153 154 int main() { 155 // freopen("in", "r", stdin); 156 // freopen("out", "w", stdout); 157 158 int n, m; 159 160 while (~scanf("%d%d", &n, &m) && (n + m)) { 161 build(n); 162 while (m--) { 163 int l, r; 164 165 scanf("%d%d", &l, &r); 166 delSeg(l, r); 167 if (node[l].key == -inf) putchar('*'); 168 else printf("%d", node[l].key); 169 putchar(' '); 170 if (node[r].key == inf) putchar('*'); 171 else printf("%d", node[r].key); 172 puts(""); 173 } 174 puts("-"); 175 } 176 177 return 0; 178 }
下面这题也是是比较简单的,只用到了反转操作,不过数列不是一个单纯的排列,所以要先处理出稳定排序后的结果,重新附上标号以后就可以直接模拟了!
HDU 1890: acm.hdu.edu.cn/showproblem.php?pid=1890
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int inf = 0x7f7f7f7f; 9 struct Node { 10 int cnt; 11 bool rev; 12 Node *c[2], *p; 13 14 Node(int _cnt = 0) { 15 cnt = _cnt; 16 rev = false; 17 c[0] = c[1] = p = NULL; 18 } 19 } *Null, *Root; 20 21 void up(Node *rt) { 22 rt->cnt = rt->c[0]->cnt + rt->c[1]->cnt + 1; 23 } 24 25 void init() { 26 Null = new Node(); 27 Root = new Node(1); 28 29 Root->c[0] = Root->p = Null; 30 Root->c[1] = new Node(1); 31 Root->c[1]->p = Root; 32 Root->c[1]->c[0] = Root->c[1]->c[1] = Null; 33 up(Root); 34 } 35 36 void down(Node *rt) { 37 Node *ls = rt->c[0], *rs = rt->c[1]; 38 39 if (rt->rev) { 40 if (ls != Null) { 41 swap(ls->c[0], ls->c[1]); 42 ls->rev = !ls->rev; 43 } 44 if (rs != Null) { 45 swap(rs->c[0], rs->c[1]); 46 rs->rev = !rs->rev; 47 } 48 rt->rev = false; 49 } 50 } 51 52 void rotate(Node *x, bool right) { 53 Node *y = x->p; 54 bool left = !right; 55 56 down(y); 57 down(x); 58 y->c[left] = x->c[right]; 59 if (x->c[right] != Null) { 60 x->c[right]->p = y; 61 } 62 x->p = y->p; 63 if (y->p != Null) { 64 if (y->p->c[0] == y) { 65 y->p->c[0] = x; 66 } else { 67 y->p->c[1] = x; 68 } 69 } 70 x->c[right] = y; 71 y->p = x; 72 73 up(y); 74 if (y == Root) Root = x; 75 } 76 77 void splay(Node *x, Node *f) { 78 down(x); 79 80 while (x->p != f) { 81 if (x->p->p == f) { 82 if (x->p->c[0] == x) { 83 rotate(x, true); 84 } else { 85 rotate(x, false); 86 } 87 } else { 88 Node *y = x->p, *z = y->p; 89 90 if (z->c[0] == y) { 91 if (y->c[0] == x) { 92 rotate(y, true); 93 rotate(x, true); 94 } else { 95 rotate(x, false); 96 rotate(x, true); 97 } 98 } else { 99 if (y->c[0] == x) { 100 rotate(x, true); 101 rotate(x, false); 102 } else { 103 rotate(y, false); 104 rotate(x, false); 105 } 106 } 107 } 108 } 109 110 up(x); 111 } 112 113 const int maxn = 100005; 114 struct List { 115 int data; 116 int pri; 117 } list[maxn]; 118 Node *rec[maxn]; 119 120 bool cmp1(List _a, List _b) { 121 if (_a.data != _b.data) return _a.data < _b.data; 122 return _a.pri < _b.pri; 123 } 124 125 bool cmp2(List _a, List _b) { 126 return _a.pri < _b.pri; 127 } 128 129 Node *getNode(int pos) { 130 Node *p = Root; 131 132 pos++; 133 while (true) { 134 down(p); 135 136 int c = p->c[0]->cnt; 137 138 if (pos == c + 1) { 139 return p; 140 } else if (pos <= c) { 141 p = p->c[0]; 142 } else { 143 pos -= c + 1; 144 p = p->c[1]; 145 } 146 } 147 } 148 149 void insPos(int data, int pos) { 150 Node *pl = getNode(pos), *pr = getNode(pos + 1); 151 152 splay(pl, Null); 153 splay(pr, pl); 154 155 Node *tmp = new Node(1); 156 157 down(pr); 158 rec[data] = tmp; 159 pr->c[0] = tmp; 160 tmp->p = pr; 161 tmp->c[0] = tmp->c[1] = Null; 162 163 splay(tmp, Null); 164 } 165 166 int getPos(Node *x) { 167 splay(x, Null); 168 169 return x->c[0]->cnt; 170 } 171 172 void reverse(int n) { 173 Node *pl = getNode(n), *pr = getNode(getPos(rec[n]) + 1); 174 175 if (pl->c[1] == rec[n]) return ; 176 splay(pl, Null); 177 splay(pr, pl); 178 179 pr = pr->c[0]; 180 down(pr); 181 pr->rev = !pr->rev; 182 swap(pr->c[0], pr->c[1]); 183 184 splay(pr, Null); 185 } 186 187 void in_tra(Node *rt) { 188 if (rt == Null) { 189 return ; 190 } 191 down(rt); 192 in_tra(rt->c[0]); 193 printf("%d %d %d p %d\n", rt, rt->c[0], rt->c[1], rt->p); 194 in_tra(rt->c[1]); 195 } 196 197 void pre(int n) { 198 sort(list, list + n, cmp1); 199 for (int i = 0; i < n; i++) { 200 list[i].data = i; 201 } 202 sort(list, list + n, cmp2); 203 for (int i = 0; i < n; i++) { 204 insPos(list[i].data, i); 205 } 206 } 207 208 void build(int n) { 209 init(); 210 for (int i = 0, x; i < n; i++) { 211 scanf("%d", &x); 212 list[i].data = x; 213 list[i].pri = i; 214 } 215 pre(n); 216 } 217 218 void deal(int n) { 219 // in_tra(Root); 220 // puts("~~~"); 221 // for (int i = 0; i < n; i++) { 222 // printf("%d %d\n", i, rec[i]); 223 // } 224 // printf("%d\n", n); 225 for (int i = 0; i < n; i++) { 226 if (i) putchar(' '); 227 printf("%d", getPos(rec[i])); 228 reverse(i); 229 } 230 puts(""); 231 } 232 233 int main() { 234 int n; 235 236 // freopen("in", "r", stdin); 237 // freopen("out", "w", stdout); 238 while (~scanf("%d", &n) && n) { 239 build(n); 240 deal(n); 241 } 242 243 return 0; 244 }
做这几题Splay Tree,暂时没遇到比较难的操作,不过Splay Tree的代码都有一定的长度的啊!如果没打好,debug起来是挺吃力的。。。囧!
另外,除了中间那题,其余两题都是用动态内存处理的!
——written by Lyon