HDU 3487:Play with Chain(Splay)
http://acm.hdu.edu.cn/showproblem.php?pid=3487
题意:有两种操作:1、Flip l r ,把 l 到 r 这段区间 reverse。2、Cut a b c ,把 a 到 b 这段区间切掉,再把这段区间接到切掉后的第 c 个数的后面。
思路:做完了上一道变态题目,做这道题目如鱼得水。Cut的时候就是把a 到 b 放到keytree的位置,记录一下当前keytree的值,然后切掉,再把切掉后的第 c 个数转到 root 的位置,再把这个记录的值重新连接回去。要注意当全部询问结束了,要把所有的rev标记pushdown。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <string> 7 #include <iostream> 8 #include <stack> 9 #include <map> 10 #include <queue> 11 using namespace std; 12 #define N 300100 13 #define INF 0x3f3f3f3f 14 #define lson ch[x][0] 15 #define rson ch[x][1] 16 #define keytree ch[ch[root][1]][0] 17 18 struct SplayTree 19 { 20 int num[N], rev[N], ch[N][2], fa[N], val[N], sz[N]; 21 int n, root, cnt, ans[N], tol; 22 23 void PushDown(int x) 24 { 25 if(rev[x]) { 26 swap(lson, rson); 27 if(lson) rev[lson] ^= 1; 28 if(rson) rev[rson] ^= 1; 29 rev[x] = 0; 30 } 31 } 32 33 void PushUp(int x) 34 { 35 sz[x] = sz[lson] + sz[rson] + 1; 36 } 37 38 int NewNode(int w, int f, int kind) 39 { 40 int x = ++cnt; 41 ch[x][0] = ch[x][1] = rev[x] = 0; 42 sz[x] = 1; val[x] = w; fa[x] = f; 43 ch[f][kind] = cnt; 44 return x; 45 } 46 47 void Build(int l, int r, int &x, int f, int kind) 48 { 49 if(l > r) return ; 50 int m = (l + r) >> 1; 51 x = NewNode(num[m], f, kind); 52 Build(l, m - 1, ch[x][0], x, 0); 53 Build(m + 1, r, ch[x][1], x, 1); 54 PushUp(x); 55 } 56 57 void Init() 58 { 59 root = cnt = tol = 0; 60 rev[0] = val[0] = fa[0] = sz[0] = ch[0][0] = ch[0][1] = 0; 61 root = NewNode(0, 0, 0); 62 ch[root][1] = NewNode(0, root, 1); 63 sz[root] = 2; 64 Build(1, n, keytree, ch[root][1], 0); 65 PushUp(ch[root][1]); PushUp(root); 66 } 67 68 void Rotate(int x, int kind) 69 { 70 int y = fa[x], z = fa[y]; 71 PushDown(y); PushDown(x); 72 ch[y][!kind] = ch[x][kind]; 73 if(ch[y][!kind]) fa[ch[y][!kind]] = y; 74 if(z) { 75 if(y == ch[z][0]) ch[z][0] = x; 76 else ch[z][1] = x; 77 } 78 fa[x] = z; fa[y] = x; 79 ch[x][kind] = y; 80 PushUp(y); 81 } 82 83 void Splay(int x, int goal) 84 { 85 while(fa[x] != goal) { 86 int y = fa[x], z = fa[y]; 87 PushDown(z); PushDown(y); PushDown(x); 88 int kind1 = x == ch[y][0]; 89 int kind2 = y == ch[z][0]; 90 if(z == goal) { 91 Rotate(x, kind1); 92 } else { 93 if(kind1 == kind2) { 94 Rotate(y, kind1); 95 } else { 96 Rotate(x, kind1); 97 } 98 Rotate(x, kind2); 99 } 100 } 101 PushUp(x); 102 if(goal == 0) root = x; 103 } 104 105 void RTO(int k, int goal) 106 { 107 int x = root; 108 PushDown(x); 109 while(k != sz[lson] + 1) { 110 if(k <= sz[lson]) x = lson; 111 else k -= sz[lson] + 1, x = rson; 112 PushDown(x); 113 } 114 Splay(x, goal); 115 } 116 117 void Cut(int l, int r, int c) 118 { 119 RTO(l, 0); 120 // Debug(); 121 RTO(r + 2, root); 122 int tmp = keytree; 123 keytree = 0; 124 // Debug(); 125 RTO(c + 1, 0); 126 // Debug(); 127 RTO(c + 2, root); 128 fa[tmp] = ch[root][1]; 129 keytree = tmp; 130 } 131 132 void Reverse(int l, int r) 133 { 134 RTO(l, 0); RTO(r + 2, root); 135 rev[keytree] ^= 1; 136 } 137 138 void Down(int x) 139 { 140 PushDown(x); 141 if(lson) Down(lson); 142 if(rson) Down(rson); 143 } 144 145 void Travel(int x) 146 { 147 if(lson) Travel(lson); 148 ans[tol++] = val[x]; 149 if(rson) Travel(rson); 150 } 151 152 void Debug() 153 { 154 Down(root); 155 Travel(root); 156 for(int i = 1; i <= n; i++) { 157 if(i == n) printf("%d\n", ans[i]); 158 else printf("%d ", ans[i]); 159 } 160 } 161 }spy; 162 163 int main() 164 { 165 int n, m; 166 while(scanf("%d%d", &n, &m)) { 167 if(n < 0 || m < 0) break; 168 spy.n = n; 169 for(int i = 1; i <= n; i++) spy.num[i] = i; 170 spy.Init(); 171 while(m--) { 172 char s[10]; 173 int a, b, c; 174 scanf("%s", s); 175 if(s[0] == 'C') { 176 scanf("%d%d%d", &a, &b, &c); 177 spy.Cut(a, b, c); 178 } else { 179 scanf("%d%d", &a, &b); 180 spy.Reverse(a, b); 181 } 182 } 183 spy.Debug(); 184 } 185 return 0; 186 }