_bzoj1500 [NOI2005]维修数列【真·Splay】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1500

注意MAX-SUM的时候,不可以是空串。

#include <cstdio>
#include <algorithm>

const int maxn = 500005;

int n, m, top, a[maxn], posi, tot, cc;
char opr[15];
struct Node {
	Node * ch[2];
	Node * fa;
	int key, sm, mxl, mxr, mxs, siz, c, mx;
	char rev;
	Node(void);
	int getsm(void) {
		return c == -666666? sm: c * siz;
	}
	int getmxl(void) {
		if (c == -666666) {
			return rev? mxr: mxl;
		}
		if (c > 0) {
			return c * siz;
		}
		return 0;
	}
	int getmxr(void) {
		if (c == -666666) {
			return rev? mxl: mxr;
		}
		if (c > 0) {
			return c * siz;
		}
		return 0;
	}
	int getmxs(void) {
		if (c == -666666) {
			return mxs;
		}
		if (c > 0) {
			return c * siz;
		}
		return 0;
	}
	int getmx(void) {
		return c == -666666? mx: c;
	}
} *nil, *root, *tnode;
Node * stk[maxn];

Node::Node(void) {
	ch[0] = ch[1] = fa = nil;
	key = sm = mxl = mxr = mxs = siz = rev = 0;
	mx = c = -666666;
}
inline void pushup(Node * x) {
	x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;
	x->sm = x->ch[0]->getsm() + x->ch[1]->getsm() + x->key;
	x->mxl = std::max(x->ch[0]->getmxl(), x->ch[0]->getsm() + x->key + x->ch[1]->getmxl());
	x->mxr = std::max(x->ch[1]->getmxr(), x->ch[1]->getsm() + x->key + x->ch[0]->getmxr());
	x->mxs = std::max(x->ch[0]->getmxs(), x->ch[1]->getmxs());
	x->mxs = std::max(x->mxs, x->ch[0]->getmxr() + x->key + x->ch[1]->getmxl());
	x->mx = std::max(x->ch[0]->getmx(), x->ch[1]->getmx());
	x->mx = std::max(x->mx, x->key);
}
inline void pushdown(Node * x) {
	if (x->c != -666666) {
		x->ch[0]->c = x->ch[1]->c = x->c;
		x->key = x->c;
		x->sm = x->c * x->siz;
		if (x->c > 0) {
			x->mxl = x->mxr = x->mxs = x->sm;
		}
		else {
			x->mxl = x->mxr = x->mxs = 0;
		}
		x->c = -666666;
	}
	if (x->rev) {
		x->rev = 0;
		x->ch[0]->rev ^= 1;
		x->ch[1]->rev ^= 1;
		std::swap(x->ch[0], x->ch[1]);
	}
}
inline void rotate(Node* x) {
	Node *y = x->fa;
	if (y == y->fa->ch[0]) {
		y->fa->ch[0] = x;
	}
	else {
		y->fa->ch[1] = x;
	}
	x->fa = y->fa;
	int dir = x == y->ch[1];
	y->ch[dir] = x->ch[dir ^ 1];
	x->ch[dir ^ 1]->fa = y;
	x->ch[dir ^ 1] = y;
	y->fa = x;
	pushup(y);
	pushup(x);
}
inline void splay(Node * x, Node * rt) {
	Node * p;
	char flag1, flag2;
	top = 0;
	for (Node * i = x; i != rt; i = i->fa) {
		stk[top++] = i;
	}
	for (int i = top - 1; ~i; --i) {
		pushdown(stk[i]);
	}
	while (x->fa != rt) {
		p = x->fa;
		if (p->fa == rt) {
			rotate(x);
		}
		else {
			flag1 = p == p->fa->ch[1];
			flag2 = x == p->ch[1];
			if (flag1 ^ flag2) {
				rotate(x);
			}
			else {
				rotate(p);
			}
			rotate(x);
		}
	}
	if (rt == nil) {
		root = x;
	}
}
inline void modify(int pos1, int pos2) {
	Node * x = root;
	pushdown(x);
	while (pos1 != x->ch[0]->siz + 1) {
		if (pos1 <= x->ch[0]->siz) {
			x = x->ch[0];
		}
		else {
			pos1 -= x->ch[0]->siz + 1;
			x = x->ch[1];
		}
		pushdown(x);
	}
	splay(x, nil);
	x = root;
	pushdown(x);
	while (pos2 != x->ch[0]->siz + 1) {
		if (pos2 <= x->ch[0]->siz) {
			x = x->ch[0];
		}
		else {
			pos2 -= x->ch[0]->siz + 1;
			x = x->ch[1];
		}
		pushdown(x);
	}
	splay(x, root);
}
inline Node* ist(int left, int right) {
	if (left > right) {
		return nil;
	}
	Node * rt = new Node, *t;
	int mid = (left + right) >> 1;
	rt->key = a[mid];
	t = ist(left, mid - 1);
	t->fa = rt;
	rt->ch[0] = t;
	t = ist(mid + 1, right);
	t->fa = rt;
	rt->ch[1] = t;
	pushup(rt);
	return rt;
}
void clear(Node * x) {
	if (x == nil) {
		return;
	}
	clear(x->ch[0]);
	clear(x->ch[1]);
	delete x;
}

int main(void) {
	//freopen("in.txt", "r", stdin);
	nil = new Node;
	root = nil;
	scanf("%d%d", &n, &m);
	for (int i = 2; i <= n + 1; ++i) {
		scanf("%d", a + i);
	}
	root = ist(1, n = n + 2);
	while (m--) {
		scanf("%s", opr);
		if (opr[2] == 'S') {	// INSERT
			scanf("%d%d", &posi, &tot);
			n += tot;
			++posi;
			modify(posi, posi + 1);
			for (int i = 1; i <= tot; ++i) {
				scanf("%d", a + i);
			}
			tnode = ist(1, tot);
			tnode->fa = root->ch[1];
			root->ch[1]->ch[0] = tnode;
			pushup(root->ch[1]);
			pushup(root);
		}
		else if (opr[2] == 'L') {	// DELETE
			scanf("%d%d", &posi, &tot);
			n -= tot;
			++posi;
			modify(posi - 1, posi + tot);
			clear(root->ch[1]->ch[0]);
			root->ch[1]->ch[0] = nil;
			pushup(root->ch[1]);
			pushup(root);
		}
		else if (opr[2] == 'K') {	// MAKE-SAME
			scanf("%d%d%d", &posi, &tot, &cc);
			++posi;
			modify(posi - 1, posi + tot);
			root->ch[1]->ch[0]->c = cc;
			pushup(root->ch[1]);
			pushup(root);
		}
		else if (opr[2] == 'V') {	// REVERSE
			scanf("%d%d", &posi, &tot);
			++posi;
			modify(posi - 1, posi + tot);
			root->ch[1]->ch[0]->rev ^= 1;
			pushup(root->ch[1]);
			pushup(root);
		}
		else if (opr[2] == 'T') {	// GET-SUM
			scanf("%d%d", &posi, &tot);
			++posi;
			modify(posi - 1, posi + tot);
			printf("%d\n", root->ch[1]->ch[0]->getsm());
		}
		else {	// MAX-SUM
			modify(1, n);
			printf("%d\n", root->ch[1]->ch[0]->getmx() > 0? root->getmxs(): root->ch[1]->ch[0]->getmx());
		}
	}
	return 0;
}

  

posted @ 2016-12-10 13:20  ciao_sora  阅读(113)  评论(0编辑  收藏  举报