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
", 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 }
原文地址:https://www.cnblogs.com/fightfordream/p/6062260.html