【HYSBZ】1500 维修数列

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<algorithm>

  4 #define oo 0x7FFFFFFF

  5 #define MAXN 1000010

  6 using namespace std;

  7 struct SplayTree {

  8     int root, size;

  9     int a[MAXN], st[MAXN], top;

 10     int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN];

 11     bool flip[MAXN];

 12     int same[MAXN], sum[MAXN], MaxL[MAXN], MaxR[MAXN], MaxM[MAXN];

 13     inline void PushUp(int x) {

 14         int L, R;

 15         L = next[x][0];

 16         R = next[x][1];

 17         num[x] = num[L] + num[R] + 1;

 18         sum[x] = sum[L] + sum[R] + key[x];

 19         MaxL[x] = max(MaxL[L], sum[L] + key[x] + max(MaxL[R], 0));

 20         MaxR[x] = max(MaxR[R], sum[R] + key[x] + max(MaxR[L], 0));

 21         MaxM[x] = max(MaxM[L], MaxM[R]);

 22         MaxM[x] = max(MaxM[x], max(MaxR[L], 0) + key[x] + max(MaxL[R], 0));

 23     }

 24     inline void PushDown(int x) {

 25         int L, R;

 26         L = next[x][0];

 27         R = next[x][1];

 28         if (flip[x]) {

 29             flip[x] = false;

 30             swap(next[x][0], next[x][1]);

 31             if (L) {

 32                 flip[L] ^= true;

 33                 swap(MaxL[L], MaxR[L]);

 34             }

 35             if (R) {

 36                 flip[R] ^= true;

 37                 swap(MaxL[R], MaxR[R]);

 38             }

 39         }

 40         if (same[x] != -oo) {

 41             if (L) {

 42                 same[L] = key[L] = same[x];

 43                 sum[L] = num[L] * same[x];

 44                 MaxL[L] = MaxR[L] = MaxM[L] = max(same[x], sum[L]);

 45             }

 46             if (R) {

 47                 same[R] = key[R] = same[x];

 48                 sum[R] = num[R] * same[x];

 49                 MaxL[R] = MaxR[R] = MaxM[R] = max(same[x], sum[R]);

 50             }

 51             same[x] = -oo;

 52         }

 53     }

 54     void NewNode(int &x, int father, int val) {

 55         if (top != -1)

 56             x = st[top--];

 57         else

 58             x = ++size;

 59         flip[x] = false;

 60         next[x][0] = next[x][1] = 0;

 61         pre[x] = father;

 62         key[x] = sum[x] = MaxL[x] = MaxR[x] = MaxM[x] = val;

 63         num[x] = 1;

 64         same[x] = -oo;

 65     }

 66     void Build(int &x, int L, int R, int father) {

 67         if (L <= R) {

 68             int mid = (L + R) >> 1;

 69             NewNode(x, father, a[mid]);

 70             Build(next[x][0], L, mid - 1, x);

 71             Build(next[x][1], mid + 1, R, x);

 72             PushUp(x);

 73         }

 74     }

 75     void Init(int n) {

 76         top = -1;

 77         root = size = 0;

 78         next[0][0] = next[0][1] = pre[0] = key[0] = num[0] = sum[0] = 0;

 79         flip[0] = false;

 80         same[0] = MaxL[0] = MaxR[0] = MaxM[0] = -oo;

 81         NewNode(root, 0, -oo);

 82         NewNode(next[root][1], root, -oo);

 83         Build(next[next[root][1]][0], 1, n, next[root][1]);

 84         PushUp(next[root][1]);

 85         PushUp(root);

 86     }

 87     void Rotate(int x, int kind) {

 88         int y, z;

 89         y = pre[x];

 90         z = pre[y];

 91         PushDown(y);

 92         next[y][!kind] = next[x][kind];

 93         pre[next[x][kind]] = y;

 94         next[z][next[z][1] == y] = x;

 95         pre[x] = z;

 96         next[x][kind] = y;

 97         pre[y] = x;

 98         PushUp(y);

 99     }

100     void Splay(int x, int goal) {

101         if (x != goal) {

102             PushDown(x);

103             while (pre[x] != goal) {

104                 if (next[pre[x]][0] == x)

105                     Rotate(x, 1);

106                 else

107                     Rotate(x, 0);

108             }

109             PushUp(x);

110             if (!goal)

111                 root = x;

112         }

113     }

114     int Select(int k) {

115         int x;

116         PushDown(root);

117         for (x = root; num[next[x][0]] + 1 != k;) {

118             if (num[next[x][0]] + 1 > k)

119                 x = next[x][0];

120             else {

121                 k -= num[next[x][0]] + 1;

122                 x = next[x][1];

123             }

124             PushDown(x);

125         }

126         return x;

127     }

128     int GetSum(int x, int y) {

129         x = Select(x - 1);

130         y = Select(y + 1);

131         Splay(x, 0);

132         Splay(y, x);

133         return sum[next[y][0]];

134     }

135     void Recycle(int x) {

136         if (x) {

137             st[++top] = x;

138             Recycle(next[x][0]);

139             Recycle(next[x][1]);

140         }

141     }

142     void Delete(int x, int y) {

143         x = Select(x - 1);

144         y = Select(y + 1);

145         Splay(x, 0);

146         Splay(y, x);

147         Recycle(next[y][0]);

148         next[y][0] = 0;

149         PushUp(y);

150         PushUp(x);

151     }

152     void Flip(int x, int y) {

153         x = Select(x - 1);

154         y = Select(y + 1);

155         Splay(x, 0);

156         Splay(y, x);

157         y = next[y][0];

158         flip[y] ^= true;

159         swap(MaxL[y], MaxR[y]);

160     }

161     void MakeSame(int x, int y, int val) {

162         int t;

163         x = Select(x - 1);

164         y = Select(y + 1);

165         Splay(x, 0);

166         Splay(y, x);

167         t = next[y][0];

168         same[t] = key[t] = val;

169         sum[t] = val * num[t];

170         MaxL[t] = MaxR[t] = MaxM[t] = max(val, sum[t]);

171         PushUp(y);

172         PushUp(x);

173     }

174     int GetMin(int x) {

175         PushDown(x);

176         while (next[x][0]) {

177             x = next[x][0];

178             PushDown(x);

179         }

180         return x;

181     }

182     void Insert(int x, int cnt) {

183         int y;

184         x = Select(x);

185         Splay(x, 0);

186         y = GetMin(next[x][1]);

187         Splay(y, x);

188         Build(next[y][0], 1, cnt, y);

189         PushUp(y);

190         PushUp(x);

191     }

192     int MaxSum(int x, int y) {

193         x = Select(x - 1);

194         y = Select(y + 1);

195         Splay(x, 0);

196         Splay(y, x);

197         return MaxM[next[y][0]];

198     }

199 } spt;

200 int main() {

201     int n, q;

202     int pos, cnt, i, val;

203     char cmd[18];

204     while (~scanf("%d%d", &n, &q)) {

205         for (i = 1; i <= n; i++)

206             scanf("%d", &spt.a[i]);

207         spt.Init(n);

208         while (q--) {

209             scanf(" %s", cmd);

210             if (strcmp(cmd, "GET-SUM") == 0) {

211                 scanf("%d%d", &pos, &cnt);

212                 printf("%d\n", spt.GetSum(pos + 1, pos + cnt));

213             } else if (strcmp(cmd, "MAX-SUM") == 0)

214                 printf("%d\n", spt.MaxSum(2, spt.num[spt.root] - 1));

215             else if (strcmp(cmd, "INSERT") == 0) {

216                 scanf("%d%d", &pos, &cnt);

217                 for (i = 1; i <= cnt; i++)

218                     scanf("%d", &spt.a[i]);

219                 spt.Insert(pos + 1, cnt);

220             } else if (strcmp(cmd, "DELETE") == 0) {

221                 scanf("%d%d", &pos, &cnt);

222                 spt.Delete(pos + 1, pos + cnt);

223             } else if (strcmp(cmd, "MAKE-SAME") == 0) {

224                 scanf("%d%d%d", &pos, &cnt, &val);

225                 spt.MakeSame(pos + 1, pos + cnt, val);

226             } else if (strcmp(cmd, "REVERSE") == 0) {

227                 scanf("%d%d", &pos, &cnt);

228                 spt.Flip(pos + 1, pos + cnt);

229             }

230         }

231     }

232     return 0;

233 }

你可能感兴趣的:(500)