POJ 3580:SuperMemo(Splay)

http://poj.org/problem?id=3580

题意:有6种操作,其中有两种之前没做过,就是Revolve操作和Min操作。Revolve一开始想着一个一个删一个一个插,觉得太暴力了,后来发现可以把要放到前面的一段切开,丢到前面去,就和上一题的Cut是一样的了。还有Min操作,一开始特别ZZ地想着只要找keytree的最左边就好了,然后发现并不是那样的,要维护一个 mi 值,一开始两个节点设成 INF,然后 pushup 的时候先把 val 赋给 mi,然后再和左右儿子对比。WA了好几次,找了下数据。。

  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 1000100
 13 #define INF 0x7fffffff
 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], col[N], mi[N];
 21     int n, root, cnt;
 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         if(col[x]) {
 32             if(lson) {
 33                 col[lson] += col[x];
 34                 val[lson] += col[x];
 35                 mi[lson] += col[x];
 36             }
 37             if(rson) {
 38                 col[rson] += col[x];
 39                 val[rson] += col[x];
 40                 mi[rson] += col[x];
 41             }
 42             col[x] = 0;
 43         }
 44     }
 45 
 46     void PushUp(int x)
 47     {
 48         sz[x] = sz[lson] + sz[rson] + 1;
 49         mi[x] = val[x];
 50         if(lson) mi[x] = min(mi[x], mi[lson]);
 51         if(rson) mi[x] = min(mi[x], mi[rson]);
 52     }
 53 
 54     int NewNode(int w, int f, int kind)
 55     {
 56         int x = ++cnt;
 57         ch[x][0] = ch[x][1] = rev[x] = col[x] = 0;
 58         sz[x] = 1; val[x] = w; fa[x] = f;
 59         mi[x] = w;
 60         ch[f][kind] = cnt;
 61         return x;
 62     }
 63 
 64     void Build(int l, int r, int &x, int f, int kind)
 65     {
 66         if(l > r) return ;
 67         int m = (l + r) >> 1;
 68         x = NewNode(num[m], f, kind);
 69         Build(l, m - 1, ch[x][0], x, 0);
 70         Build(m + 1, r, ch[x][1], x, 1);
 71         PushUp(x);
 72     }
 73 
 74     void Init()
 75     {
 76         root = cnt = 0;
 77         rev[0] = val[0] = col[0] = fa[0] = sz[0] = ch[0][0] = ch[0][1] = 0;
 78         mi[0] = INF;
 79         root = NewNode(INF, 0, 0);
 80         ch[root][1] = NewNode(INF, root, 1);
 81         val[ch[root][1]] = INF;
 82         sz[root] = 2;
 83         Build(1, n, keytree, ch[root][1], 0);
 84         PushUp(ch[root][1]); PushUp(root);
 85     }
 86 
 87     void Rotate(int x, int kind)
 88     {
 89         int y = fa[x], z = fa[y];
 90         PushDown(y); PushDown(x);
 91         ch[y][!kind] = ch[x][kind];
 92         if(ch[y][!kind]) fa[ch[y][!kind]] = y;
 93         if(z) {
 94             if(y == ch[z][0]) ch[z][0] = x;
 95             else ch[z][1] = x;
 96         }
 97         fa[x] = z; fa[y] = x;
 98         ch[x][kind] = y;
 99         PushUp(y);
100     }
101 
102     void Splay(int x, int goal)
103     {
104 //        printf("%d, %d
", x, fa[x]);
105         PushDown(x);
106         while(fa[x] != goal) {
107             int y = fa[x], z = fa[y];
108             PushDown(z); PushDown(y); PushDown(x);
109             int kind1 = x == ch[y][0];
110             int kind2 = y == ch[z][0];
111             if(z == goal) {
112                 Rotate(x, kind1);
113             } else {
114                 if(kind1 == kind2) {
115                     Rotate(y, kind1);
116                 } else {
117                     Rotate(x, kind1);
118                 }
119                 Rotate(x, kind2);
120             }
121         }
122         PushUp(x);
123         if(goal == 0) root = x;
124     }
125 
126     void RTO(int k, int goal)
127     {
128         int x = root;
129         PushDown(x);
130         while(k != sz[lson] + 1) {
131             if(k <= sz[lson]) x = lson;
132             else k -= sz[lson] + 1, x = rson;
133             PushDown(x);
134         }
135 //        printf("%d, %d, %d
", x, val[x], goal);
136         Splay(x, goal);
137     }
138 
139     void Add(int l, int r, int d)
140     {
141         RTO(l, 0); RTO(r + 2, root);
142         col[keytree] += d;
143         val[keytree] += d;
144         mi[keytree] += d;
145         PushUp(ch[root][1]); PushUp(root);
146     }
147 
148     void Reverse(int l, int r)
149     {
150         RTO(l, 0); RTO(r + 2, root);
151         rev[keytree] ^= 1;
152         PushUp(ch[root][1]); PushUp(root);
153     }
154 
155     void Cut(int l, int r, int c)
156     {
157         RTO(l, 0); RTO(r + 2, root);
158         PushUp(ch[root][1]); PushUp(root);
159 //      Debug();
160 //      puts("---------");
161         int tmp = keytree;
162         keytree = 0;
163         RTO(c, 0); RTO(c + 1, root);
164         keytree = tmp;
165         fa[tmp] = ch[root][1];
166         PushUp(ch[root][1]); PushUp(root);
167     }
168 
169     void Revolve(int l, int r, int t)
170     {
171         t = (t % (r - l + 1) + (r - l + 1)) % (r - l + 1);
172         if(t == 0) return ;
173         Cut(r - t + 1, r, l);
174 //        Debug();
175         PushUp(ch[root][1]); PushUp(root);
176     }
177 
178     void Insert(int index, int w)
179     {
180         RTO(index + 1, 0); RTO(index + 2, root);
181         keytree = NewNode(w, ch[root][1], 0);
182         PushUp(ch[root][1]); PushUp(root);
183     }
184 
185     void Delete(int index)
186     {
187         RTO(index, 0); RTO(index + 2, root);
188         keytree = 0;
189         PushUp(ch[root][1]); PushUp(root);
190     }
191 
192     int Query(int l, int r)
193     {
194         RTO(l, 0);
195         RTO(r + 2, root);
196 //        Debug();
197         return mi[keytree];
198     }
199 
200     void Travel(int x)
201     {
202         if(lson) Travel(lson);
203         printf("ttt : %d, %d, %d
", x, val[x], mi[x]);
204         if(rson) Travel(rson);
205     }
206 
207     void Debug()
208     {
209         Travel(root);
210     }
211 }spy;
212 
213 int main()
214 {
215     int n;
216     while(~scanf("%d", &n)) {
217         spy.n = n;
218         for(int i = 1; i <= n; i++) scanf("%d", &spy.num[i]);
219         spy.Init();
220         int m;
221         scanf("%d", &m);
222         while(m--) {
223             char s[10];
224             int a, b, c;
225             scanf("%s", s);
226             if(s[0] == 'A') {
227                 scanf("%d%d%d", &a, &b, &c);
228                 spy.Add(a, b, c);
229             } else if(s[0] == 'M') {
230                 scanf("%d%d", &a, &b);
231                 printf("%d
", spy.Query(a, b));
232             } else if(s[0] == 'R' && s[3] == 'E') {
233                 scanf("%d%d", &a, &b);
234                 spy.Reverse(a, b);
235             } else if(s[0] == 'R' && s[3] == 'O') {
236                 scanf("%d%d%d", &a, &b, &c);
237                 spy.Revolve(a, b, c);
238             } else if(s[0] == 'I') {
239                 scanf("%d%d", &a, &b);
240                 spy.Insert(a, b);
241             } else if(s[0] == 'D') {
242                 scanf("%d", &a);
243                 spy.Delete(a);
244             }
245 //            spy.Debug();
246         }
247     }
248     return 0;
249 }
250 
251 /*
252 5
253 1
254 2
255 3
256 4
257 5
258 2
259 REVOLVE 1 5 4
260 MIN 4 5
261 
262 10
263 1 2 3 4 5 6 7 8 9 10
264 15
265 ADD 4 8 3
266 MIN 5 7
267 MIN 7 10
268 REVERSE 2 5
269 MIN 2 6
270 MIN 2 3
271 INSERT 3 4
272 MIN 3 4
273 MIN 5 10
274 DELETE 6
275 MIN 3 5
276 MIN 4 4
277 REVOLVE 3 6 7
278 MIN 5 8
279 MIN 7 10
280 **************************
281 282 283 284 285 286 287 288 289 290 291 */
原文地址:https://www.cnblogs.com/fightfordream/p/6063541.html