【bzoj1500】[NOI2005]维修数列

题目描述:


输入:

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

输出:
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

样例输入:

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

样例输出:

-1
10
1
10

题解:

splay果体。

immortalCO:用treap更快,而且还更好写。

反正这题机房里的其他神犇都是1A+差不多1h写完的,而我蒟蒻调了整整三天才调出来。QAQ

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
#else
	#define debug(...)
#endif

#define R register
#define getc() (S == T&&(T = (S = B) + fread(B, 1, 1<<15, stdin), S == T)?EOF: * S ++ )
#define gmax(_a,  _b) ((_a) > (_b) ? (_a) : (_b))
#define gmin(_a,  _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a,  _b) (_a < (_b) ? _a  =  (_b) : 0)
#define cmin(_a,  _b) (_a > (_b) ? _a  =  (_b) : 0)
char B[1<<15],  * S = B,  * T = B;
inline int FastIn()
{
	R char ch;R int cnt = 0;R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch !=  '-') ;
	ch  ==  '-' ?minus = 1:cnt = ch-'0';
	while (ch = getc(), ch >=  '0' && ch  <=  '9') cnt  =  cnt  *  10  +  ch - '0';
	return minus?-cnt:cnt;
}
#define maxn 1000010
int fa[maxn], ch[maxn][2], a[maxn], size[maxn], cnt;
int sum[maxn], lmx[maxn], rmx[maxn], mx[maxn], v[maxn], id[maxn], root;
bool rev[maxn], tag[maxn];
inline void swap(int &a, int &b)
{
	R int tmp = a;a = b;b = tmp;
}
inline void update(R int x)
{
	R int ls = ch[x][0], rs = ch[x][1];
	size[x] = size[ls] + size[rs] + 1;
	sum[x] = sum[ls] + sum[rs] + v[x];
	mx[x] = gmax(mx[ls], mx[rs]);
	cmax(mx[x], lmx[rs] + rmx[ls] + v[x]);
	lmx[x] = gmax(lmx[ls], sum[ls] + v[x] + lmx[rs]);
	rmx[x] = gmax(rmx[rs], sum[rs] + v[x] + rmx[ls]);
}
inline void pushdown(R int x)
{
	R int ls = ch[x][0], rs = ch[x][1];
	if (tag[x])
	{
		rev[x] = tag[x] = 0;
		if (ls) tag[ls] = 1, v[ls] = v[x], sum[ls] = size[ls] * v[x];
		if (rs) tag[rs] = 1, v[rs] = v[x], sum[rs] = size[rs] * v[x];
		if (v[x]>= 0)
		{
			if (ls) lmx[ls] = rmx[ls] = mx[ls] = sum[ls];
			if (rs) lmx[rs] = rmx[rs] = mx[rs] = sum[rs];
		}
		else
		{
			if (ls) lmx[ls] = rmx[ls] = 0, mx[ls] = v[x];
			if (rs) lmx[rs] = rmx[rs] = 0, mx[rs] = v[x];
		}	
	}
	if (rev[x])
	{
		rev[x] ^= 1; rev[ls] ^= 1; rev[rs] ^= 1;
		swap(lmx[ls], rmx[ls]);swap(lmx[rs], rmx[rs]);
		swap(ch[ls][0], ch[ls][1]); swap(ch[rs][0], ch[rs][1]);
	}
}
inline void rotate(R int x)
{
	R int f = fa[x], gf = fa[f], d = ch[f][1] == x;
	if (f == root) root = x;
	(ch[f][d] = ch[x][d ^ 1]) > 0 ? fa[ch[f][d]] = f : 0;
	(fa[x] = gf) > 0 ? ch[gf][ch[gf][1] == f] = x : 0;
	fa[ch[x][d ^ 1] = f] = x;
	update(f);
}
inline void splay(R int x, R int rt)
{
	while (fa[x] != rt)
	{
		R int f = fa[x], gf = fa[f];
		if (gf != rt) rotate((ch[gf][1] == f) ^ (ch[f][1] == x) ? x : f);
		rotate(x);
	}
	update(x);
}
void build(R int l, R int r, R int rt)
{
	if (l > r) return ;
	R int mid = l + r >> 1, now = id[mid], last = id[rt];
	if (l == r)
	{
		sum[now] = a[l];
		size[now] = 1;
		tag[now] = rev[now] = 0;
		if (a[l] >= 0) lmx[now] = rmx[now] = mx[now] = a[l];
		else lmx[now] = rmx[now] = 0, mx[now] = a[l];
	}
	else
	{
		build(l, mid - 1, mid);
		build(mid + 1, r, mid);
	}
	v[now] = a[mid];
	fa[now] = last;
	update(now);
	ch[last][mid >= rt] = now;
}
int find(R int x, R int rank)
{
	if (tag[x] || rev[x]) pushdown(x);
	R int ls = ch[x][0], rs = ch[x][1], lsize = size[ls];
	if (lsize + 1 == rank) return x;
	if (lsize >= rank)
		return find(ls, rank);
	else
		return find(rs, rank - lsize - 1);
}
inline int prepare(R int l, R int tot)
{
	R int x = find(root, l - 1), y = find(root, l + tot);
	splay(x, 0);
	splay(y, x);
	return ch[y][0];
}
std::queue <int> q;
inline void Insert(R int left, R int tot)
{
	for (R int i = 1; i <= tot; ++i ) a[i] = FastIn();
	for (R int i = 1; i <= tot; ++i )
		if (!q.empty()) id[i] = q.front(), q.pop();
		else id[i] = ++cnt;
	build(1, tot, 0);
	R int z = id[(1 + tot) >> 1];
	R int x = find(root, left), y = find(root, left + 1);
	splay(x, 0);
	splay(y, x);
	fa[z] = y;
	ch[y][0] = z;
	update(y);
	update(x);
}
void rec(R int x)
{
	if (!x) return ;
	R int ls = ch[x][0], rs = ch[x][1];
	rec(ls); rec(rs); q.push(x);
	fa[x] = ch[x][0] = ch[x][1] = 0;
	tag[x] = rev[x] = 0;
}
inline void Delete(R int l, R int tot)
{
	R int x = prepare(l, tot), f = fa[x];
	rec(x); ch[f][0] = 0;
	update(f); update(fa[f]);
}
inline void Makesame(R int l, R int tot, R int val)
{
	R int x = prepare(l, tot), y = fa[x];
	v[x] = val; tag[x] = 1; sum[x] = size[x] * val;
	if (val >= 0) lmx[x] = rmx[x] = mx[x] = sum[x];
	else lmx[x] = rmx[x] = 0, mx[x] = val;
	update(y); update(fa[y]);
}
inline void Reverse(R int l, R int tot)
{
	R int x = prepare(l, tot), y = fa[x];
	if (!tag[x])
	{
		rev[x] ^= 1;
		swap(ch[x][0], ch[x][1]);
		swap(lmx[x], rmx[x]);
		update(y); update(fa[y]);
	}
}
inline void Query(R int l, R int tot)
{
	R int x = prepare(l, tot);
	printf("%d\n",sum[x] );
}
#define inf ((1 << 30))
int main()
{
	R int n = FastIn(),  m = FastIn(), l, tot, val;
	R char op, op2;
	mx[0] = a[1] = a[n + 2] = -inf;
	for (R int i = 2; i <= n + 1; i++ )
	{
		a[i] = FastIn();
	}
	for (R int i = 1; i <= n + 2; ++i) id[i] = i;
	n += 2; cnt = n; root = (n + 1) >> 1;
	build(1, n, 0);
	for (R int i = 1; i <= m; i++ )
	{
		op = getc();
		while (op < 'A' || op > 'Z') op = getc();
		getc(); op2 = getc();getc();getc();getc();getc();
		if (op == 'M' && op2 == 'X')
		{
			printf("%d\n",mx[root] );
		}
		else
		{
			l = FastIn() + 1; tot = FastIn();
			if (op == 'I') Insert(l, tot);
			if (op == 'D') Delete(l, tot);
			if (op == 'M') val = FastIn(), Makesame(l, tot, val);
			if (op == 'R')
				Reverse(l, tot);
			if (op == 'G')
				Query(l, tot);
		}
	}
	return 0;
}
/*
9 14
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
GET-SUM 8 4
MAX-SUM
DELETE 12 1
GET-SUM 8 4
MAX-SUM
MAKE-SAME 3 3 2
GET-SUM 5 4
MAX-SUM
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
*/



 

posted @ 2016-03-23 16:33  cot  阅读(118)  评论(0编辑  收藏  举报