同OJ1552
标签:
同OJ1552
Q:哎不是同一道题吗为什么分两篇博客来写?
A:当然是来骗浏览量了233333333,这里还是会放代码的,当然你左转BZOJ1552的题解也行。
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct spaly 4 { 5 int c[2], fa, siz, rev; 6 }a[100005]; 7 pair<int, int> b[100005]; 8 9 void push_up(int k) 10 { 11 a[k].siz = a[a[k].c[0]].siz + a[a[k].c[1]].siz + 1; 12 } 13 14 void push_down(int k) 15 { 16 if(a[k].rev) 17 { 18 swap(a[k].c[0], a[k].c[1]), a[k].rev = 0; 19 a[a[k].c[0]].rev ^= 1, a[a[k].c[1]].rev ^= 1; 20 } 21 } 22 23 void rotate(int &k, int x) 24 { 25 int y = a[x].fa, z = a[y].fa; 26 int dy = a[y].c[1] == x, dz = a[z].c[1] == y; 27 if(k == y) k = x, a[x].fa = z; 28 else a[z].c[dz] = x, a[x].fa = z; 29 a[y].c[dy] = a[x].c[!dy], a[a[x].c[!dy]].fa = y; 30 a[x].c[!dy] = y, a[y].fa = x; 31 push_up(y); 32 } 33 34 void splay(int &k, int x) 35 { 36 while(k != x) 37 { 38 int y = a[x].fa, z = a[y].fa; 39 push_down(z), push_down(y), push_down(x); 40 if(k != y) 41 if(a[y].c[1] == x ^ a[z].c[1] == y) rotate(k, x); 42 else rotate(k, y); 43 rotate(k, x); 44 } 45 push_up(x); 46 } 47 48 int find(int k, int x) 49 { 50 if(!k) return 0; 51 push_down(k); 52 if(x <= a[a[k].c[0]].siz) return find(a[k].c[0], x); 53 if(x == a[a[k].c[0]].siz + 1) return k; 54 return find(a[k].c[1], x - a[a[k].c[0]].siz - 1); 55 } 56 57 int main() 58 { 59 int n, root, pos; 60 while(~scanf("%d", &n) && n) 61 { 62 for(int i = 1; i <= n; i++) 63 { 64 scanf("%d", &b[i].first); 65 b[i].second = i + 1; 66 } 67 sort(b + 1, b + n + 1); 68 for(int i = 1; i <= n + 2; i++) 69 { 70 a[i].fa = i + 1, a[i].c[0] = i - 1; 71 a[i].siz = i, a[i].c[1] = a[i].rev = 0; 72 } 73 a[n + 2].fa = 0, root = n + 2; 74 for(int i = 1; i <= n; i++) 75 { 76 splay(root, b[i].second); 77 pos = a[a[root].c[0]].siz; 78 printf("%d", pos); 79 if(i != n) printf(" "); 80 splay(root, find(root, i)); 81 splay(a[root].c[1], find(root, pos + 2)); 82 a[a[a[root].c[1]].c[0]].rev ^= 1; 83 } 84 puts(""); 85 } 86 return 0; 87 }
[BZOJ3506] [Cqoi2014] 排序机械臂 (splay)
标签:
原文地址:http://www.cnblogs.com/CtrlCV/p/5415751.html