1. 程式人生 > >[BZOJ1500][NOI2005]維修數列

[BZOJ1500][NOI2005]維修數列

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]維修數列