【POJ】3580 SuperMemo

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define oo 0x7FFFFFFF
  5 #define MAXN 200010
  6 using namespace std;
  7 struct SplayTree {
  8     int size, root, top;
  9     int st[MAXN], a[MAXN];
 10     int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN];
 11     int add[MAXN], mini[MAXN];
 12     bool flip[MAXN];
 13     inline void PushUp(int x) {
 14         num[x] = num[next[x][0]] + num[next[x][1]] + 1;
 15         mini[x] = min(mini[next[x][0]], mini[next[x][1]]);
 16         mini[x] = min(mini[x], key[x]);
 17     }
 18     inline void PushDown(int x) {
 19         int L, R;
 20         L = next[x][0];
 21         R = next[x][1];
 22         if (add[x]) {
 23             if (L) {
 24                 add[L] += add[x];
 25                 key[L] += add[x];
 26                 mini[L] += add[x];
 27             }
 28             if (R) {
 29                 add[R] += add[x];
 30                 key[R] += add[x];
 31                 mini[R] += add[x];
 32             }
 33             add[x] = 0;
 34         }
 35         if (flip[x]) {
 36             flip[L] ^= true;
 37             flip[R] ^= true;
 38             swap(next[x][0], next[x][1]);
 39             flip[x] = false;
 40         }
 41     }
 42     void NewNode(int &x, int father, int val) {
 43         if (top != -1)
 44             x = st[top--];
 45         else
 46             x = ++size;
 47         next[x][0] = next[x][1] = add[x] = 0;
 48         pre[x] = father;
 49         key[x] = mini[x] = val;
 50         num[x] = 1;
 51         flip[x] = false;
 52     }
 53     void Build(int &x, int L, int R, int father) {
 54         if (L <= R) {
 55             int mid = (L + R) >> 1;
 56             NewNode(x, father, a[mid]);
 57             Build(next[x][0], L, mid - 1, x);
 58             Build(next[x][1], mid + 1, R, x);
 59             PushUp(x);
 60         }
 61     }
 62     void Init(int n) {
 63         root = size = 0;
 64         top = -1;
 65         flip[0] = false;
 66         next[0][0] = next[0][1] = pre[0] = num[0] = add[0] = 0;
 67         key[0] = mini[0] = oo;
 68         NewNode(root, 0, oo);
 69         NewNode(next[root][1], root, oo);
 70         Build(next[next[root][1]][0], 1, n, next[root][1]);
 71         PushUp(next[root][1]);
 72         PushUp(root);
 73     }
 74     void Rotate(int x, int kind) {
 75         int y, z;
 76         y = pre[x];
 77         z = pre[y];
 78         PushDown(y);
 79         next[y][!kind] = next[x][kind];
 80         pre[next[x][kind]] = y;
 81         next[z][next[z][1] == y] = x;
 82         pre[x] = z;
 83         next[x][kind] = y;
 84         pre[y] = x;
 85         PushUp(y);
 86     }
 87     void Splay(int x, int goal) {
 88         if (x != goal) {
 89             PushDown(x);
 90             while (pre[x] != goal) {
 91                 if (next[pre[x]][0] == x)
 92                     Rotate(x, 1);
 93                 else
 94                     Rotate(x, 0);
 95             }
 96             PushUp(x);
 97             if (!goal)
 98                 root = x;
 99         }
100     }
101     int Select(int k) {
102         int x;
103         PushDown(root);
104         for (x = root; num[next[x][0]] + 1 != k;) {
105             if (num[next[x][0]] + 1 > k)
106                 x = next[x][0];
107             else {
108                 k -= num[next[x][0]] + 1;
109                 x = next[x][1];
110             }
111             PushDown(x);
112         }
113         return x;
114     }
115     void Add(int x, int y, int val) {
116         int t;
117         x = Select(x - 1);
118         y = Select(y + 1);
119         Splay(x, 0);
120         Splay(y, x);
121         t = next[y][0];
122         add[t] += val;
123         key[t] += val;
124         mini[t] += val;
125         PushUp(y);
126         PushUp(x);
127     }
128     void Flip(int x, int y) {
129         x = Select(x - 1);
130         y = Select(y + 1);
131         Splay(x, 0);
132         Splay(y, x);
133         flip[next[y][0]] ^= true;
134     }
135     void Revolve(int x, int y, int t) {
136         int cnt = y - x + 1;
137         t %= cnt;
138         if (t < 0)
139             t += cnt;
140         if (t) {
141             Flip(x, y - t);
142             Flip(y - t + 1, y);
143             Flip(x, y);
144         }
145     }
146     void Insert(int x, int val) {
147         int a, b;
148         a = Select(x);
149         b = Select(x + 1);
150         Splay(a, 0);
151         Splay(b, a);
152         NewNode(next[b][0], b, val);
153         PushUp(b);
154         PushUp(a);
155     }
156     void Delete(int x) {
157         int a, b;
158         a = Select(x - 1);
159         b = Select(x + 1);
160         Splay(a, 0);
161         Splay(b, a);
162         st[++top] = next[b][0];
163         next[b][0] = 0;
164         PushUp(b);
165         PushUp(a);
166     }
167     int MIN(int x, int y) {
168         x = Select(x - 1);
169         y = Select(y + 1);
170         Splay(x, 0);
171         Splay(y, x);
172         return mini[next[y][0]];
173     }
174 } spt;
175 int main() {
176     char cmd[18];
177     int n, q, i;
178     int x, y, val;
179     while (~scanf("%d", &n)) {
180         for (i = 1; i <= n; i++)
181             scanf("%d", &spt.a[i]);
182         spt.Init(n);
183         scanf("%d", &q);
184         while (q--) {
185             scanf(" %s", cmd);
186             if (strcmp(cmd, "ADD") == 0) {
187                 scanf("%d%d%d", &x, &y, &val);
188                 spt.Add(x + 1, y + 1, val);
189             } else if (strcmp(cmd, "REVERSE") == 0) {
190                 scanf("%d%d", &x, &y);
191                 spt.Flip(x + 1, y + 1);
192             } else if (strcmp(cmd, "REVOLVE") == 0) {
193                 scanf("%d%d%d", &x, &y, &val);
194                 spt.Revolve(x + 1, y + 1, val);
195             } else if (strcmp(cmd, "INSERT") == 0) {
196                 scanf("%d%d", &x, &val);
197                 spt.Insert(x + 1, val);
198             } else if (strcmp(cmd, "DELETE") == 0) {
199                 scanf("%d", &x);
200                 spt.Delete(x + 1);
201             } else {
202                 scanf("%d%d", &x, &y);
203                 printf("%d\n", spt.MIN(x + 1, y + 1));
204             }
205         }
206     }
207     return 0;
208 }
原文地址:https://www.cnblogs.com/DrunBee/p/2641081.html