BZOJ-1500 [NOI2005]维修数列

神级数据结构维护题。。。Splay练手题。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <queue>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define inf 1000000000
#define maxn 1000005
using namespace std;
inline int read()
{
	int x=0, f=1; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*f;
}
int c[maxn][2], h[maxn], size[maxn], sum[maxn], ls[maxn], rs[maxn], ms[maxn], v[maxn], rt, id[maxn], a[maxn];
int cnt;
char s[10];
bool rev[maxn], tag[maxn];
queue <int> q;
inline void update(int x)
{
	int l=c[x][0], r=c[x][1];
	sum[x]=sum[l]+sum[r]+v[x];
	size[x]=size[l]+size[r]+1;
	ms[x]=max(ms[l], ms[r]);
	ms[x]=max(ms[x], rs[l]+v[x]+ls[r]);
	ls[x]=max(ls[l], sum[l]+v[x]+ls[r]);
	rs[x]=max(rs[r], rs[l]+v[x]+sum[r]);
}
void pushdown(int x)
{
	int l=c[x][0], r=c[x][1];
	if (tag[x])
	{
		rev[x]=tag[x]=0;
		if (l) tag[l]=1, v[l]=v[x], sum[l]=v[l]*size[l];
		if (r) tag[r]=1, v[r]=v[x], sum[r]=v[r]*size[r];
		if (v[x]>=0)
		{
			if (l) ls[l]=rs[l]=ms[l]=sum[l];
			if (r) ls[r]=rs[r]=ms[r]=sum[r];
		}
		else 
		{
			if (l) ls[l]=rs[l]=0, ms[l]=v[l];
			if (r) ls[r]=rs[r]=0, ms[r]=v[r];
		}
	}
	if (rev[x])
	{
		rev[x]^=1; rev[l]^=1; rev[r]^=1;
		swap(ls[l], rs[l]); swap(ls[r], rs[r]);
		swap(c[l][0], c[l][1]); swap(c[r][0], c[r][1]);
	}
}
inline void rotate(int x, int &k)
{
	int y=h[x], z=h[y], l=(c[y][1]==x), r=l^1;
	if (y==k) k=x; else c[z][c[z][1]==y]=x;
	h[c[x][r]]=y, h[y]=x, h[x]=z;
	c[y][l]=c[x][r]; c[x][r]=y;
	update(y), update(x);
}
inline void Splay(int x, int &k)
{
	/* while (x!=k)
	{
		int y=h[x], z=h[y];
		if (y!=k)
		{
			(c[y][0]==x)^(c[z][0]==y) ? rotate(x, k) : rotate(y, k);
		}
		rotate(x, k);
	} */
	while (x!=k) rotate(x, k);
}
int Find(int x, int k)
{
	pushdown(x);
	int l=c[x][0], r=c[x][1];
	if (size[l]+1==k) return x;
	if (size[l]>=k) return Find(l, k);
	return Find(r, k-size[l]-1);
}
void Del(int x)
{
	if (!x) return;
	int l=c[x][0], r=c[x][1];
	Del(l); Del(r); q.push(x);
	h[x]=c[x][0]=c[x][1]=0;
	tag[x]=rev[x]=0;
}
inline int Split(int k, int n)
{
	int x=Find(rt, k), y=Find(rt, k+n+1);
	Splay(x, rt); Splay(y, c[x][1]);
	return c[y][0];
}
inline void QSum(int k, int n){int x=Split(k, n); printf("%d\n", sum[x]);}
inline void Same(int k, int n, int val)
{
	int x=Split(k, n), y=h[x];
	v[x]=val; tag[x]=1; sum[x]=size[x]*val;
	if (val>=0) ls[x]=rs[x]=ms[x]=sum[x]; else ls[x]=rs[x]=0, ms[x]=val;
	update(y), update(h[y]);
}
inline void Rever(int k, int n)
{
	int x=Split(k, n), y=h[x];
	if (tag[x]) return;
	rev[x]^=1;
	swap(c[x][0], c[x][1]);
	swap(ls[x], rs[x]);
	update(y), update(h[y]);
}
inline void Delete(int k, int n)
{
	int x=Split(k, n), y=h[x];
	Del(x); c[y][0]=0; 
	update(y), update(h[y]);
}
void Build(int l, int r, int f)
{
	if (l>r) return;
	int mid=(l+r)>>1, now=id[mid], last=id[f];
	if (l==r)
	{
		sum[now]=a[l], size[now]=1, tag[now]=rev[now]=0;
		if (a[l]>=0) ls[now]=rs[now]=ms[now]=a[l]; else ls[now]=rs[now]=0, ms[now]=a[l];
	}
	else Build(l, mid-1, mid), Build(mid+1, r, mid);
	v[now]=a[mid], h[now]=last, update(now);
	c[last][mid>f]=now;
}
inline void Insert(int k, int n)
{
	rep(i, 1, n) a[i]=read();
	rep(i, 1, n) if (!q.empty()) id[i]=q.front(), q.pop(); else id[i]=++cnt;
	Build(1, n, 0); 
	int x=Find(rt, k+1), y=Find(rt, k+2), z=id[(1+n)>>1];
	Splay(x, rt); Splay(y, c[x][1]);
	h[z]=y, c[y][0]=z;
	update(y), update(x);
}
int main()
{
	int n=read(), m=read(); 
	ms[0]=a[1]=a[n+2]=-inf;
	rep(i, 1, n) a[i+1]=read();
	rep(i, 1, n+2) id[i]=i;
	Build(1, n+2, 0);
	rt=(n+3)>>1, cnt=n+2;
	rep(i, 1, m)
	{
		scanf("%s", s);
		if (s[0]=='I') 
			{int a=read(), b=read(); Insert(a, b);}
		else if (s[0]=='D')
			{int a=read(), b=read(); Delete(a, b);}
		else if (s[0]=='R')
			{int a=read(), b=read(); Rever(a, b);}
		else if (s[0]=='G')
			{int a=read(), b=read(); QSum(a, b);}
		else if (s[2]=='K')
			{int a=read(), b=read(); Same(a, b, read());}
		else
			printf("%d\n", ms[rt]);
	}
	return 0;
}
posted @ 2015-05-05 16:55  NanoApe  阅读(140)  评论(0编辑  收藏  举报
AmazingCounters.com