仍然是询问区间最大连续和,只不过多了插入和删除操作。

线段树搞不定了。。伸展树来了。

插入删除偷懒那样写了,加了读入优化卡过的。

  1 #include<cstdio>
  2 #include<iostream>
  3 #define MAX(a,b) ((a)>(b)?(a):(b))
  4 #define oo 1000000000
  5 #define MAXN 200010
  6 using namespace std;
  7 int n, a[MAXN];
  8 struct SplayTree {
  9     int root, size;
 10     int next[MAXN][2], pre[MAXN];
 11     int num[MAXN], key[MAXN];
 12     int left[MAXN], right[MAXN], sum[MAXN], val[MAXN];
 13     void NewNode(int &x, int father, int nb) {
 14         x = ++size;
 15         next[x][0] = next[x][1] = 0;
 16         pre[x] = father;
 17         num[x] = 1;
 18         key[x] = left[x] = right[x] = sum[x] = val[x] = nb;
 19     }
 20     inline void PushUp(int x) {
 21         int L, R;
 22         L = next[x][0], R = next[x][1];
 23         num[x] = num[L] + num[R] + 1;
 24         sum[x] = sum[L] + sum[R] + key[x];
 25         left[x] = MAX(left[L],sum[L]+key[x]+MAX(left[R],0));
 26         right[x] = MAX(right[R],sum[R]+key[x]+MAX(right[L],0));
 27         val[x] = MAX(val[L],val[R]);
 28         val[x] = MAX(val[x],key[x]+MAX(right[L],0)+MAX(left[R],0));
 29     }
 30     void Build(int L, int R, int &x, int father) {
 31         if (L <= R) {
 32             int mid = (L + R) >> 1;
 33             NewNode(x, father, a[mid]);
 34             Build(L, mid - 1, next[x][0], x);
 35             Build(mid + 1, R, next[x][1], x);
 36             PushUp(x);
 37         }
 38     }
 39     void Init() {
 40         size = root = 0;
 41         next[0][0] = next[0][1] = 0;
 42         pre[0] = 0;
 43         sum[0] = num[0] = 0;
 44         key[0] = left[0] = right[0] = val[0] = -oo;
 45         NewNode(root, 0, -oo);
 46         NewNode(next[root][1], root, -oo);
 47         Build(1, n, next[next[root][1]][0], next[root][1]);
 48         PushUp(next[root][1]);
 49         PushUp(root);
 50     }
 51     void Rotate(int x, int kind) {
 52         int y, z;
 53         y = pre[x];
 54         z = pre[y];
 55         next[y][!kind] = next[x][kind];
 56         pre[next[x][kind]] = y;
 57         next[z][next[z][1] == y] = x;
 58         pre[x] = z;
 59         next[x][kind] = y;
 60         pre[y] = x;
 61         PushUp(y);
 62     }
 63     void Splay(int x, int goal) {
 64         if (x != goal) {
 65             while (pre[x] != goal) {
 66                 if (next[pre[x]][0] == x)
 67                     Rotate(x, 1);
 68                 else
 69                     Rotate(x, 0);
 70             }
 71             PushUp(x);
 72             if (!goal)
 73                 root = x;
 74         }
 75     }
 76     int Select(int k) {
 77         int x;
 78         for (x = root; num[next[x][0]] + 1 != k;) {
 79             if (k <= num[next[x][0]])
 80                 x = next[x][0];
 81             else {
 82                 k -= num[next[x][0]] + 1;
 83                 x = next[x][1];
 84             }
 85         }
 86         return x;
 87     }
 88     void Insert(int k, int val) {
 89         int a, b;
 90         a = Select(k);
 91         b = Select(k + 1);
 92         Splay(a, 0);
 93         Splay(b, a);
 94         NewNode(next[b][0], b, val);
 95         PushUp(b);
 96         PushUp(a);
 97     }
 98     void Delete(int k) {
 99         int a, b;
100         a = Select(k);
101         b = Select(k + 2);
102         Splay(a, 0);
103         Splay(b, a);
104         next[b][0] = 0;
105         PushUp(b);
106         PushUp(a);
107     }
108     void Update(int k, int val) {
109         int a;
110         a = Select(k + 1);
111         key[a] = val;
112         Splay(a, 0);
113     }
114     int Query(int x, int y) {
115         x = Select(x);
116         y = Select(y + 2);
117         Splay(x, 0);
118         Splay(y, x);
119         return val[next[y][0]];
120     }
121 } spt;
122 int INT() {
123     int res;
124     char ch;
125     bool neg;
126     while (ch = getchar(), !isdigit(ch) && ch != '-')
127         ;
128     if (ch == '-') {
129         res = 0;
130         neg = true;
131     } else {
132         res = ch - '0';
133         neg = false;
134     }
135     while (ch = getchar(), isdigit(ch))
136         res = res * 10 + ch - '0';
137     return neg ? -res : res;
138 }
139 char CHAR() {
140     char res;
141     while (res = getchar(), !isalpha(res))
142         ;
143     return res;
144 }
145 int main() {
146     char ch;
147     int i, q, x, y;
148     while (~scanf("%d", &n)) {
149         for (i = 1; i <= n; i++)
150             a[i] = INT();
151         spt.Init();
152         q = INT();
153         while (q--) {
154             ch = CHAR(), x = INT();
155             if (ch != 'D')
156                 y = INT();
157             if (ch == 'I')
158                 spt.Insert(x, y);
159             else if (ch == 'D')
160                 spt.Delete(x);
161             else if (ch == 'R')
162                 spt.Update(x, y);
163             else
164                 printf("%d\n", spt.Query(x, y));
165         }
166     }
167     return 0;
168 }
posted on 2012-08-29 15:27  DrunBee  阅读(414)  评论(0编辑  收藏  举报