【POJ3580】【splay版】SuperMemo
Description
Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1, A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:
- ADD x y D: Add D to each number in sub-sequence {Ax ... Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
- REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
- REVOLVE x y T: rotate sub-sequence {Ax ... Ay} T times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
- INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
- DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
- MIN x y: query the participant what is the minimum number in sub-sequence {Ax ... Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2
To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.
Input
The first line contains n (n ≤ 100000).
The following n lines describe the sequence.
Then follows M (M ≤ 100000), the numbers of operations and queries.
The following M lines describe the operations and queries.
Output
For each "MIN" query, output the correct answer.
Sample Input
5 1 2 3 4 5 2 ADD 2 4 1 MIN 4 5
Sample Output
5
Source
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 #include <utility> 7 #include <iomanip> 8 #include <string> 9 #include <cmath> 10 #include <queue> 11 #include <assert.h> 12 #include <map> 13 #include <ctime> 14 #include <cstdlib> 15 #define LOCAL 16 const int MAXN = 200000 + 10; 17 const int INF = 100000000; 18 const int SIZE = 450; 19 const int maxnode = 0x7fffffff + 10; 20 using namespace std; 21 struct SPLAY{ 22 struct Node{ 23 int val, Min;//分别为值,最小值,大小和lazy下标 24 int size, lazy; 25 bool turn; 26 Node *parent, *ch[2]; 27 28 //初始化 29 void NEW(int x){ 30 Min = val = x; 31 size = 1; 32 lazy = turn = 0; 33 parent = ch[0] = ch[1] = NULL; 34 } 35 int cmp(){ 36 if (parent->ch[0] == this) return 0; 37 if (parent->ch[1] == this) return 1; 38 } 39 //还是不要写在里面了.. 40 /*void pushdown(){ 41 42 } 43 void update(){ 44 size = 1; 45 if (x->ch[0] != NULL) size += x->ch[0]->size; 46 if (x->ch[1] != NULL) size += x->ch[0]->size; 47 } 48 */ 49 }mem[MAXN], *root;//mem为静态数组 50 int tot; 51 52 int get(Node *&x){return (x == NULL ? 0 : x->size);} 53 //————————————————————这一部分不能卸载里面 54 //更新 55 void update(Node *&x){ 56 if (x == NULL) return; 57 x->size = 1; 58 x->Min = x->val; 59 if (x->ch[0] != NULL) {x->Min = min(x->Min, x->ch[0]->Min);x->size += x->ch[0]->size;} 60 if (x->ch[1] != NULL) {x->Min = min(x->Min, x->ch[1]->Min);x->size += x->ch[1]->size;} 61 } 62 void pushdown(Node *&x){//标记下传 63 if (x == NULL) return; 64 if (x->lazy){ 65 int tmp = x->lazy; 66 x->val += tmp; 67 if (x->ch[0] != NULL) {x->ch[0]->lazy += tmp;x->ch[0]->Min += tmp;} 68 if (x->ch[1] != NULL) {x->ch[1]->lazy += tmp;x->ch[1]->Min += tmp;} 69 x->lazy = 0; 70 } 71 if (x->turn){//翻转 72 swap(x->ch[0], x->ch[1]);//swap内部用什么实现的呢? 73 74 if (x->ch[0] != NULL) x->ch[0]->turn ^= 1; 75 if (x->ch[1] != NULL) x->ch[1]->turn ^= 1; 76 x->turn = 0; 77 } 78 } 79 80 //———————————————————————————— 81 //旋转,1为右旋, 0为左旋 82 void Rotate(Node *&x, int d){//不用引用也可以 83 Node *y = x->parent; 84 pushdown(y);//注意顺序 85 pushdown(x); 86 pushdown(x->ch[d]);//这个不要忘了 87 88 y->ch[d ^ 1] = x->ch[d]; 89 if (x->ch[d] != NULL) x->ch[d]->parent = y; 90 x->parent = y->parent; 91 if (y->parent != NULL){ 92 if (y->parent->ch[0] == y) y->parent->ch[0] = x; 93 else y->parent->ch[1] = x; 94 } 95 x->ch[d] = y; 96 y->parent = x; 97 update(y); 98 if (y == root) root = x;//如果是引用要小心root被传下去 99 } 100 void debug(){ 101 Node *p = new Node; 102 root = new Node; 103 root->ch[1] = p; 104 p->parent = root; 105 printf("%d", p->cmp()); 106 } 107 //注意我写的这个跟下午那个不一样,下午那个好麻烦 108 void splay(Node *&x, Node *&y){ 109 pushdown(x); 110 while (x != y){ 111 if(x->parent == y){ 112 if (y->ch[0] == x) Rotate(x, 1); 113 else Rotate(x,0); 114 break; 115 }else{ 116 Node *y = x->parent, *z = y->parent;//注意一定要这样弄一下 117 if (z->ch[0] == y) 118 if (y->ch[0] == x) Rotate(y,1),Rotate(x, 1); 119 else Rotate(x, 0), Rotate(x, 1); 120 else if (y->ch[1] == x) Rotate(y, 0), Rotate(x, 0); 121 else Rotate(x, 1), Rotate(x, 0); 122 if (z == y) break; 123 } 124 update(x); 125 } 126 update(x); 127 } 128 //寻找第k大 129 void find(Node *&t, int k){ 130 int tmp; 131 Node *p = root; 132 while (1){ 133 pushdown(p); 134 tmp = get(p->ch[0]); 135 if (k == (tmp + 1)) break; 136 if (k <= tmp) p = p->ch[0]; 137 else {k -= tmp + 1, p = p->ch[1];} 138 } 139 pushdown(p); 140 splay(p, t); 141 } 142 //插入操作 143 void Insert(int pos, int val){ 144 //还是卡出来 145 find(root, pos + 1); 146 find(root->ch[1], pos + 2); 147 Node *t = &mem[tot++], *x = root->ch[1]; 148 pushdown(root); 149 pushdown(x); 150 t->NEW(val); 151 //直接拆开放中间,放在root->ch[1]->ch[0]应该也可以 152 t->ch[1] = x; 153 x->parent = t; 154 root->ch[1] = t; 155 t->parent = root; 156 splay(x, root); 157 } 158 //区间加 159 void Add(int l, int r, int x){ 160 find(root, l); 161 find(root->ch[1] , r + 2); 162 Node *t = root->ch[1]->ch[0]; 163 pushdown(t); 164 update(t); 165 t->Min += x; 166 t->lazy += x; 167 splay(t, root); 168 } 169 //翻转操作 170 void Reverse(int l, int r){ 171 find(root, l); 172 find(root->ch[1], r + 2); 173 root->ch[1]->ch[0]->turn ^= 1; 174 Node *x = root->ch[1]->ch[0]; 175 splay(x, root); 176 } 177 //交换操作,这一段我是看别人的.... 178 void Revolve(int l, int r, int t){ 179 Node *p1, *p2; 180 181 find(root, l); 182 find(root->ch[1], r + 2); 183 find(root->ch[1]->ch[0], r + 1 - t); 184 185 p1 = root->ch[1]->ch[0]; 186 pushdown(p1); 187 p2 = p1->ch[1]; 188 p1->ch[1] = NULL; 189 find(root->ch[1]->ch[0], l + 1); 190 p1 = root->ch[1]->ch[0]; 191 pushdown(p1); 192 p1->ch[0] = p2; 193 p2->parent = p1; 194 splay(p2, root); 195 } 196 int getMin(int l, int r){ 197 find(root, l); 198 find(root->ch[1], r + 2); 199 Node *x = root->ch[1]; 200 pushdown(x); 201 x = x->ch[0]; 202 pushdown(x); 203 update(x); 204 return x->Min; 205 } 206 void Erase(int pos){//删除 207 find(root, pos); 208 find(root->ch[1], pos + 2); 209 pushdown(root->ch[1]); 210 root->ch[1]->ch[0] = NULL; 211 Node *x = root->ch[1]; 212 splay(x, root); 213 } 214 void init(){ 215 //注意还要加一个正无穷 216 tot = 0; 217 root = &mem[tot++]; 218 root->NEW(INF); 219 root->ch[1] = &mem[tot++]; 220 root->ch[1]->NEW(INF); 221 } 222 void print(Node *t){ 223 if (t == NULL) return; 224 print(t->ch[0]); 225 printf("%d ", t->val); 226 if (t->parent != NULL) printf("%d\n", t->parent->val); 227 print(t->ch[1]); 228 } 229 }A; 230 231 int n, m; 232 //注意在这里为了防止掉到0,所以每个位置都要+1 233 void init(){//初始化 234 A.init(); 235 scanf("%d", &n); 236 for (int i = 0 ; i < n; i++){ 237 int x; 238 scanf("%d", &x); 239 A.Insert(i, x); 240 //printf("%d\n", A.root->val); 241 } 242 //A.print(A.root); 243 } 244 void work(){ 245 scanf("%d", &m); 246 for (int i = 1; i <= m; i++){//询问,按顺序来。。 247 char str[20]; 248 scanf("%s", str); 249 if (str[0] == 'A'){ 250 int l, r, x; 251 scanf("%d%d%d", &l, &r, &x); 252 A.Add(l, r, x); 253 }else if (str[0] == 'R'){ 254 int l, r; 255 scanf("%d%d", &l, &r); 256 if (str[3] == 'E') A.Reverse(l, r); 257 else{ 258 int x, len; 259 scanf("%d", &x); 260 len = r - l + 1; 261 x = (x % len + len) % len; 262 if (x == 0 || l == r) continue;//我开始居然傻逼的写在前面.... 263 A.Revolve(l, r, x); 264 } 265 }else if (str[0] == 'I'){ 266 int l, x; 267 scanf("%d%d", &l, &x); 268 A.Insert(l, x); 269 }else if (str[0] == 'D'){ 270 int l; 271 scanf("%d", &l); 272 A.Erase(l); 273 }else if (str[0] == 'M'){ 274 int l, r; 275 scanf("%d%d", &l, &r); 276 printf("%d\n", A.getMin(l, r)); 277 } 278 } 279 } 280 void debug(){ 281 282 } 283 284 int main(){ 285 286 init(); 287 work(); 288 //debug(); 289 //A.debug(); 290 return 0; 291 }