题意:
splay模板题,支持插入,删除,修改,区间最大子段和。
splay调起来好累...
注意inf别开太大了,要保证-2inf不会溢出。
2016.2.2 09:14
发现有两个函数写重了,更新下代码。
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 200005, inf = 0x3f3f3f3f; int n, num[maxn]; inline int iread() { int f = 1, x = 0; char ch = getchar(); for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; return f * x; } int son[maxn][2], val[maxn], pre[maxn], ans[maxn], lx[maxn], rx[maxn], sum[maxn], size[maxn]; int tot1, tot2, sta[maxn], root; inline void newnode(int &x, int c, int f) { x = tot2 ? sta[tot2--] : ++tot1; son[x][0] = son[x][1] = 0; pre[x] = f; size[x] = 1; val[x] = ans[x] = lx[x] = rx[x] = sum[x] = c; } inline void pushup(int x) { int l = son[x][0], r = son[x][1]; size[x] = size[l] + size[r] + 1; sum[x] = sum[l] + sum[r] + val[x]; lx[x] = max(lx[l], sum[l] + val[x] + max(lx[r], 0)); rx[x] = max(rx[r], sum[r] + val[x] + max(rx[l], 0)); ans[x] = max(max(ans[l], ans[r]), max(lx[r], 0) + val[x] + max(rx[l], 0)); } inline void build(int &x, int l, int r, int f) { if(l > r) return; int mid = l + r >> 1; newnode(x, num[mid], f); build(son[x][0], l, mid - 1, x); build(son[x][1], mid + 1, r, x); pushup(x); } inline void init() { tot1 = tot2 = root = 0; son[0][0] = son[0][1] = pre[0] = size[0] = sum[0] = 0; lx[0] = rx[0] = val[0] = ans[0] = -inf; newnode(root, -inf, 0); newnode(son[root][1], -inf, root); build(son[son[root][1]][0], 1, n, son[root][1]); pushup(son[root][1]); pushup(root); } inline void rotate(int x) { int y = pre[x], z = pre[y], type = son[y][1] == x; pre[son[y][type] = son[x][!type]] = y; pre[x] = z; if(z) son[z][son[z][1] == y] = x; pre[son[x][!type] = y] = x; pushup(y); pushup(x); } inline void splay(int x, int goal) { while(pre[x] != goal) { int y = pre[x], z = pre[y]; if(z == goal) rotate(x); else if(son[z][0] == y ^ son[y][0] == x) rotate(x), rotate(x); else rotate(y), rotate(x); } if(goal == 0) root = x; } inline int find(int k) { int x = root; while(k != size[son[x][0]] + 1) if(k <= size[son[x][0]]) x = son[x][0]; else k -= size[son[x][0]] + 1, x = son[x][1]; return x; } inline void insert(int pos, int c) { int l = find(pos), r = find(pos + 1); splay(l, 0); splay(r, root); newnode(son[son[root][1]][0], c, son[root][1]); pushup(son[root][1]); pushup(root); } inline void erase(int pos) { int l = find(pos), r = find(pos + 2); splay(l, 0); splay(r, root); sta[++tot2] = son[son[root][1]][0]; son[son[root][1]][0] = 0; pushup(son[root][1]); pushup(root); } inline void replace(int pos, int c) { int x = find(pos + 1); val[x] = c; splay(x, 0); } inline int query(int x, int y) { int l = find(x), r = find(y + 2); splay(l, 0); splay(r, root); return ans[son[son[root][1]][0]]; } int main() { n = iread(); for(int i = 1; i <= n; i++) num[i] = iread(); init(); int m = iread(); while(m--) { char ch = getchar(); for(; ch != 'I' && ch != 'D' && ch != 'R' && ch != 'Q'; ch = getchar()); int pos = iread(); if(ch == 'I') { // n++; int c = iread(); insert(pos, c); } else if(ch == 'D') { // n--; erase(pos); } else if(ch == 'R') { int c = iread(); replace(pos, c); } else if(ch == 'Q') { int c = iread(); printf("%d\n", query(pos, c)); } } return 0; }