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\n", 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\n", 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\n", 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\n", 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 8 282 9 283 2 284 7 285 4 286 2 287 3 288 4 289 7 290 9 291 */