【SPOJ-GSS6】Can you answer these queries VI【Splay】

题意:

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


你可能感兴趣的:(splay)