输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。
//bzoj1500[NOI2005]维修数列 Splay #include<cstdio> #include<cstring> #include<algorithm> #define inf 0x3f3f3f3f using namespace std; int N, M, cnt, c[500050]; struct NODE { int lsum, rsum, totsum, maxsum, size, dk, dv, v, k; bool rev; NODE *l, *r, *f; void init(int kk, int vv){k=kk;v=vv;size=1;dv=inf;totsum=lsum=rsum=maxsum=v; l=r=f=0;dk=rev=0;} }*ROOT, *MIN, *MAX, *P; int read() { int x=0; bool fu=false; char c=getchar(); while((c<'0'||c>'9')&&c!='-')c=getchar(); if(c=='-')fu=true,c=getchar(); while(c>='0' && c<='9')x=x*10+c-'0',c=getchar(); return (fu?-x:x); } void swap(int &a, int &b) {int t=a; a=b; b=t;} void pushdown(NODE *x) { if(x->dv<inf) { x->v=x->dv; x->totsum=x->v*x->size; x->lsum=x->rsum=x->maxsum=max(x->v,x->totsum); if(x->l)x->l->dv=x->dv; if(x->r)x->r->dv=x->dv; x->dv=inf; } if(x->dk) { x->k+=x->dk; if(x->l)x->l->dk+=x->dk; if(x->r)x->r->dk+=x->dk; x->dk=0; } if(x->rev) { int sl=0, sr=0; if(x->l)sl=x->l->size,x->l->rev=!(x->l->rev); if(x->r)sr=x->r->size,x->r->rev=!(x->r->rev); x->k=x->k-sl+sr; if(x->l)x->l->dk+=sr+1; if(x->r)x->r->dk+=-sl-1; swap(x->l,x->r); swap(x->lsum,x->rsum); x->rev=false; } } void update(NODE *x) { pushdown(x); if(x->l)pushdown(x->l); if(x->r)pushdown(x->r); int t; x->size=1; if(x->l)x->size+=x->l->size; if(x->r)x->size+=x->r->size; x->totsum=x->v; if(x->l)x->totsum+=x->l->totsum; if(x->r)x->totsum+=x->r->totsum; t=x->v; if(x->l)t+=max(0,x->l->rsum);if(x->r)t+=max(0,x->r->lsum); if(x->l)t=max(t,x->l->maxsum);if(x->r)t=max(t,x->r->maxsum); x->maxsum=t; if(x->l) { t=max(x->l->lsum,x->l->totsum+x->v); if(x->r)t=max(t,x->l->totsum + x->v + max(0,x->r->lsum) ); } else if(x->r)t=x->v+max(0,x->r->lsum); x->lsum=t; if(x->r) { t=max(x->r->rsum,x->v+x->r->totsum); if(x->l)t=max(t,x->r->totsum + x->v + max(0,x->l->rsum)); } else if(x->l)t=x->v+max(0,x->l->rsum); x->rsum=t; } void zig(NODE *x) { NODE *y=x->f; pushdown(y),pushdown(x); if(y->f->l==y)y->f->l=x; else y->f->r=x; x->f=y->f; y->l=x->r; if(x->r)x->r->f=y; x->r=y;y->f=x; update(y);update(x); } void zag(NODE *x) { NODE *y=x->f; pushdown(y),pushdown(x); if(y->f->l==y)y->f->l=x; else y->f->r=x; x->f=y->f; y->r=x->l; if(x->l)x->l->f=y; x->l=y;y->f=x; update(y);update(x); } void splay(NODE *x, NODE *F) { while(x->f!=F) { NODE *y=x->f; if(y->f==F) if(y->l==x)zig(x); else zag(x); else if(y->f->l==y) if(y->l==x)zig(y),zig(x); else zag(x),zig(x); else if(y->r==x)zag(y),zag(x); else zig(x),zag(x); } } NODE* find(NODE *x, int k) { NODE *t; pushdown(x); if(x->k==k)t=x; if(x->k>k)t=find(x->l,k); if(x->k<k)t=find(x->r,k); update(x); return t; } NODE* get(int k, int v) { NODE *t; t=P;P=P->f; if(P->l==t)P->l=0;else P->r=0; while(P->l||P->r) if(P->l)P=P->l;else P=P->r; t->init(k,v); return t; } void ins(NODE *t) { P->l=t;t->f=P; while(P->l||P->r) if(P->l)P=P->l;else P=P->r; } NODE* build(int l, int r) { int mid=(l+r)>>1; NODE *p=get(mid,c[mid]); if(l==r)return p; if(l!=mid)p->l=build(l,mid-1),p->l->f=p; p->r=build(mid+1,r),p->r->f=p; update(p); return p; } int main() { char s[100], ch; int x, i, pos, tot, j; NODE *p, *t; P=new NODE; for(i=2;i<=500005;i++) { t=new NODE; t->init(0,0); t->f=P;P->r=t; P=t; } N=read();M=read(); { cnt=0; MIN=get(0,0); MAX=get(1,0); ROOT=get(123,0); ROOT->l=MIN;MIN->f=ROOT; MIN->r=MAX;MAX->f=MIN; for(i=1;i<=N;i++)c[i]=read(); MAX->k+=N; MAX->l=build(1,N);MAX->l->f=MAX; update(MAX);update(MIN); for(i=1;i<=M;i++) { scanf("%s",s); switch(s[0]) { case 'I': pos=read();tot=read(); for(j=pos+1;j<=pos+tot;j++)c[j]=read(); p=find(ROOT->l,pos);t=find(ROOT->l,pos+1); splay(p,ROOT);splay(t,p); t->dk+=tot;pushdown(t); t->l=build(pos+1,pos+tot);t->l->f=t; update(t);update(p); break; case 'D': pos=read();tot=read();if(!tot)break; p=find(ROOT->l,pos-1);t=find(ROOT->l,pos+tot); splay(p,ROOT);splay(t,p); ins(t->l);t->l=0; t->dk-=tot;pushdown(t); update(t);update(p); break; case 'R': pos=read();tot=read();if(!tot)break; p=find(ROOT->l,pos-1);t=find(ROOT->l,pos+tot); splay(p,ROOT);splay(t,p); update(p); t->l->rev=!(t->l->rev); break; case 'G': pos=read();tot=read();if(!tot){printf("0\n");break;} p=find(ROOT->l,pos-1);t=find(ROOT->l,pos+tot); splay(p,ROOT);splay(t,p); printf("%d\n",t->l->totsum); break; case 'M': if(s[2]=='K') { pos=read();tot=read();c[0]=read();if(!tot)break; p=find(ROOT->l,pos-1);t=find(ROOT->l,pos+tot); splay(p,ROOT);splay(t,p); t->l->dv=c[0];pushdown(t->l); update(t);update(p); break; } splay(MIN,ROOT);splay(MAX,MIN); pushdown(MAX->l);printf("%d\n",MAX->l->maxsum); } } } return 0; }