[BZOJ1500][NOI2005]維修數列
阿新 • • 發佈:2017-12-30
bzoj -- pri || == pac root org uil
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;
}
[BZOJ1500][NOI2005]維修數列