【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 }

你可能感兴趣的:(super)