[BZOJ1500][NOI2005]维修数列

BZOJ
Luogu
题目不放了

题解

这道题没有题解
仅此

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 2e9
const int _ = 500050;
int n,m,fa[_],ls[_],rs[_],val[_],sigma[_],sz[_],rev[_],tag[_],pre[_],suf[_],sum[_],Stack[_],a[_],top,root;
char s[_];
int gi()
{
	int x=0,w=1;char ch=getchar();
	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if (ch=='-') w=0,ch=getchar();
	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return w?x:-x;
}
void pushup(int x)
{
	sz[x]=sz[ls[x]]+sz[rs[x]]+1;
	sigma[x]=sigma[ls[x]]+sigma[rs[x]]+val[x];
	pre[x]=max(pre[ls[x]],sigma[ls[x]]+val[x]+pre[rs[x]]);
	suf[x]=max(suf[rs[x]],sigma[rs[x]]+val[x]+suf[ls[x]]);
	sum[x]=max(max(sum[ls[x]],sum[rs[x]]),suf[ls[x]]+val[x]+pre[rs[x]]);
}
void pushdown(int x)
{
	if (tag[x])
	{
		if (ls[x]) 
		{
			tag[ls[x]]=1,val[ls[x]]=val[x],sigma[ls[x]]=val[ls[x]]*sz[ls[x]];
			if (val[x]>=0) pre[ls[x]]=suf[ls[x]]=sum[ls[x]]=sigma[ls[x]];
			else pre[ls[x]]=suf[ls[x]]=0,sum[ls[x]]=val[ls[x]];
		}
		if (rs[x]) 
		{
			tag[rs[x]]=1,val[rs[x]]=val[x],sigma[rs[x]]=val[rs[x]]*sz[rs[x]];
			if (val[x]>=0) pre[rs[x]]=suf[rs[x]]=sum[rs[x]]=sigma[rs[x]];
			else pre[rs[x]]=suf[rs[x]]=0,sum[rs[x]]=val[rs[x]];
		}
		tag[x]=rev[x]=0;
	}
	if (rev[x]) 
	{
		swap(ls[ls[x]],rs[ls[x]]);
		swap(ls[rs[x]],rs[rs[x]]);
		swap(pre[ls[x]],suf[ls[x]]);
		swap(pre[rs[x]],suf[rs[x]]);
		if (ls[x]) rev[ls[x]]^=1;
		if (rs[x]) rev[rs[x]]^=1;
		rev[x]=0;
	}
}
void R_rotate(int x)
{
	int y=fa[x],z=fa[y];
	ls[y]=rs[x];
	if (rs[x]) fa[rs[x]]=y;
	fa[x]=z;
	if (z) if (y==ls[z]) ls[z]=x;else rs[z]=x;
	rs[x]=y;fa[y]=x;
	pushup(y);
}
void L_rotate(int x)
{
	int y=fa[x],z=fa[y];
	rs[y]=ls[x];
	if (ls[x]) fa[ls[x]]=y;
	fa[x]=z;
	if (z) if (y==ls[z]) ls[z]=x;else rs[z]=x;
	ls[x]=y;fa[y]=x;
	pushup(y);
}
void splay(int x,int goal)
{
	while (fa[x]!=goal)
	{
		int y=fa[x],z=fa[y];
		if (z==goal)
			if (x==ls[y]) R_rotate(x);
			else L_rotate(x);
		else
			if (y==ls[z])
				if (x==ls[y]) R_rotate(y),R_rotate(x);
				else L_rotate(x),R_rotate(x);
			else
				if (x==ls[y]) R_rotate(x),L_rotate(x);
				else L_rotate(y),L_rotate(x);
	}
	if (!goal) root=x;
	pushup(x);
}
int Rank(int k)
{
	int x=root;
	while (x)
	{
		pushdown(x);
		if (k<=sz[ls[x]]) x=ls[x];
		else if (k==sz[ls[x]]+1) return x;
		else k-=sz[ls[x]]+1,x=rs[x];
	}
}
int Build(int l,int r,int father)
{
	if (l>r) return 0;
	int x=Stack[top--];
	fa[x]=father;
	int mid=l+r>>1;
	if (l==r)
	{
		val[x]=sigma[x]=sum[x]=a[mid];
		pre[x]=suf[x]=max(0,a[mid]);
		sz[x]=1;return x;
	}
	val[x]=sum[x]=a[mid];
	ls[x]=Build(l,mid-1,x);
	rs[x]=Build(mid+1,r,x);
	pushup(x);
	return x;
}
void Insert()
{
	int pos=gi(),tot=gi();if (!tot) return;
	for (int i=1;i<=tot;i++) a[i]=gi();
	int L=Rank(pos+1);splay(L,0);
	int R=Rank(pos+2);splay(R,L);
	ls[R]=Build(1,tot,R);
	pushup(R);pushup(L);
}
void Clear(int x)
{
	fa[x]=ls[x]=rs[x]=0;
	val[x]=sz[x]=sigma[x]=pre[x]=suf[x]=0;sum[x]=-inf;
	rev[x]=tag[x]=0;
}
void Reuse(int x)
{
	if (!x) return;
	if (ls[x]) Reuse(ls[x]);
	if (rs[x]) Reuse(rs[x]);
	Clear(x);
	Stack[++top]=x;
}
void Delete()
{
	int pos=gi(),tot=gi();if (!tot) return;
	int L=Rank(pos);splay(L,0);
	int R=Rank(pos+tot+1);splay(R,L);
	Reuse(ls[R]);ls[R]=0;
	pushup(R);pushup(L);
}
void Make_Same()
{
	int pos=gi(),tot=gi(),c=gi();
	int L=Rank(pos);splay(L,0);
	int R=Rank(pos+tot+1);splay(R,L);
	int x=ls[R];
	val[x]=c;tag[x]=1;
	sigma[x]=sz[x]*c;
	if (c>=0) pre[x]=suf[x]=sum[x]=sigma[x];
	else pre[x]=suf[x]=0,sum[x]=c;
	pushup(R);pushup(L);
}
void Reverse()
{
	int pos=gi(),tot=gi();
	int L=Rank(pos);splay(L,0);
	int R=Rank(pos+tot+1);splay(R,L);
	int x=ls[R];
	if (!tag[x])
	{
		rev[x]^=1;
		swap(ls[x],rs[x]);
		swap(pre[x],suf[x]);
		pushup(R);pushup(L);
	}
}
void Get_Sum()
{
	int pos=gi(),tot=gi();
	int L=Rank(pos);splay(L,0);
	int R=Rank(pos+tot+1);splay(R,L);
	printf("%d\n",sigma[ls[R]]);
}
void Max_Sum()
{
	printf("%d\n",sum[root]);
}
int main()
{
	for (int i=500010;i;i--)
		Stack[++top]=i;
	n=gi();m=gi();Clear(0);
	a[1]=a[n+2]=-inf;
	for (int i=2;i<=n+1;i++) a[i]=gi();
	root=Build(1,n+2,0);
	while (m--)
	{
		scanf("%s",s);
		if (s[0]=='I') Insert();
		if (s[0]=='D') Delete();
		if (s[0]=='M'&&s[2]=='K') Make_Same();
		if (s[0]=='R') Reverse();
		if (s[0]=='G') Get_Sum();
		if (s[0]=='M'&&s[2]=='X') Max_Sum();
	}
	return 0;
}
posted @ 2017-12-30 16:48  租酥雨  阅读(220)  评论(0编辑  收藏  举报