洛谷P2042 [NOI2005]维护数列
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<stack> #define Tp Treap* #define DTp pair<Tp,Tp> #define ft first #define sc second #define INF 0x7f7f7f7f #define MAXN 500000+10 using namespace std; int n,m; int a[MAXN]; struct Treap{ Tp l;Tp r; int key,fix; int size,sum,lx,rx,mx,tag; }; Tp root; stack<Tp> s; Tp new_node(int v){ Tp ret; if(s.empty())ret=new Treap; else ret=s.top(),s.pop(); ret->l=ret->r=NULL; ret->key=ret->sum=v; ret->lx=ret->rx=ret->mx=v; ret->tag=-INF; ret->size=1,ret->fix=rand(); return ret; } int Size(Tp A){return (A?A->size:0);} int Sum(Tp A){return (A?A->sum:0);} int Lx(Tp A){return (A?A->lx:-INF);} int Rx(Tp A){return (A?A->rx:-INF);} int Mx(Tp A){return (A?A->mx:-INF);} void upd(Tp A){ A->size=Size(A->l)+Size(A->r)+1; A->sum=Sum(A->l)+Sum(A->r)+A->key; A->mx=max(max(Mx(A->l),Mx(A->r)),A->key+max(Rx(A->l),0)+max(Lx(A->r),0)); A->lx=max(Lx(A->l),Sum(A->l)+A->key+max(Lx(A->r),0)); A->rx=max(Rx(A->r),Sum(A->r)+A->key+max(Rx(A->l),0)); } void Print(Tp A){ if(!A)return; // pushdown(A); // printf("key=%d,size=%d,sum=%d,lx=%d,rx=%d,mx=%d\n",A->key,A->size,A->sum,A->lx,A->rx,A->mx); Print(A->l); printf("%d ",A->key); Print(A->r); if(A==root)printf("\n"); } void update(Tp A,int x){ if(!A||-INF==x)return; if(x!=INF){ A->tag=x; A->key=x; A->sum=x*A->size; A->mx=A->lx=A->rx=(x>0?A->sum:x); } else{ if(A->tag!=INF&&A->tag!=-INF)return; swap(A->l,A->r); swap(A->lx,A->rx); A->tag=-A->tag; } } void pushdown(Tp A){ update(A->l,A->tag); update(A->r,A->tag); A->tag=-INF; } Tp build(int L,int R){ if(L>R)return NULL; int mid=(L+R)>>1; Tp ret=new_node(a[mid]); ret->l=build(L,mid-1); ret->r=build(mid+1,R); upd(ret); return ret; } Tp Merge(Tp A,Tp B){ if(!A)return B; if(!B)return A; if(A->fix<B->fix){ pushdown(A); A->r=Merge(A->r,B); upd(A); return A; } else{ pushdown(B); B->l=Merge(A,B->l); upd(B); return B; } } DTp Split(Tp A,int k){ if(!A)return DTp(NULL,NULL); pushdown(A); DTp y; if(Size(A->l)>=k){ y=Split(A->l,k); A->l=y.sc; upd(A); y.sc=A; } else{ y=Split(A->r,k-Size(A->l)-1); A->r=y.ft; upd(A); y.ft=A; } return y; } int pos,len; void Insert(){ scanf("%d%d",&pos,&len); for(int i=1;i<=len;i++)scanf("%d",&a[i]); DTp x=Split(root,pos); root=Merge(x.ft,Merge(build(1,len),x.sc)); } void Del(Tp A){ if(!A)return; s.push(A); Del(A->l); Del(A->r); } void Delete(){ scanf("%d%d",&pos,&len); DTp x=Split(root,pos-1); DTp y=Split(x.sc,len); Del(y.ft); root=Merge(x.ft,y.sc); } void MakeSame(){ int v; scanf("%d%d%d",&pos,&len,&v); DTp x=Split(root,pos-1); DTp y=Split(x.sc,len); update(y.ft,v); root=Merge(x.ft,Merge(y.ft,y.sc)); } void Rev(){ scanf("%d%d",&pos,&len); DTp x=Split(root,pos-1); DTp y=Split(x.sc,len); update(y.ft,INF); root=Merge(x.ft,Merge(y.ft,y.sc)); } int GetSum(){ scanf("%d%d",&pos,&len); if(!len)return 0; DTp x=Split(root,pos-1); DTp y=Split(x.sc,len); int ans=y.ft->sum; root=Merge(x.ft,Merge(y.ft,y.sc)); return ans; } int MaxSum(){ return root->mx; } void init(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]); root=build(1,n); } void solve(){ char s[20]; while(m--){ scanf("%s",s); if('I'==s[0])Insert(); else if('D'==s[0])Delete(); else if('M'==s[0]&&'E'==s[3])MakeSame(); else if('R'==s[0])Rev(); else if('G'==s[0])printf("%d\n",GetSum()); else printf("%d\n",MaxSum()); } } int main() { // freopen("testdata.in.txt","r",stdin); // freopen("my.out","w",stdout); init(); solve(); return 0; }