仍然是询问区间最大连续和,只不过多了插入和删除操作。
线段树搞不定了。。伸展树来了。
插入删除偷懒那样写了,加了读入优化卡过的。
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 }