bzoj 1500 维修数列
Description
Input
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。
Sample Input
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
-1
10
1
10
10
1
10
code:
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define MAXN 500005 using namespace std; int lst[MAXN],n,m; int read(){ int x=0,f=1; char ch=getchar(); for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f; for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48); return x*f; } struct node{ int r,v,s,filp,lmaxn,rmaxn,maxn,sum; bool tag; node *ch[2]; void Maintain(); node(){ r=0;v=0;s=0; filp=0;sum=0;tag=0; maxn=lmaxn=rmaxn=-inf; ch[0]=ch[1]=NULL; } void push_down(); node(int x); void* operator new(size_t); void operator delete (void* p); }*null=new node(),*C,*mempool,*root; typedef pair<node*,node*>pa; vector<node*>bin; void change_tag(node *p,int val){ if(p==null)return; p->rmaxn=p->lmaxn=p->maxn=max(val,val*p->s); p->sum=val*p->s; p->v=val; p->tag=1; } void change_filp(node *p){ if(p==null)return; p->filp^=1; swap(p->lmaxn,p->rmaxn); } node :: node(int x){ v=x;r=rand();s=1; filp=tag=0; lmaxn=rmaxn=maxn=sum=v; ch[0]=ch[1]=null; } void node :: push_down(){ if(this==null)return; if(filp){ filp^=1; change_filp(ch[0]); change_filp(ch[1]); swap(ch[0],ch[1]); } if(tag){ change_tag(ch[0],v); change_tag(ch[1],v); tag=0; } } void node :: Maintain(){ if(this==null)return; push_down(); s=ch[0]->s+ch[1]->s+1; sum=ch[0]->sum+ch[1]->sum+v; maxn = max(max(ch[0]->rmaxn,0)+v+max(ch[1]->lmaxn,0),max(ch[0]->maxn,ch[1]->maxn)); lmaxn = max(ch[0]->lmaxn,ch[0]->sum+v+max(ch[1]->lmaxn,0)); rmaxn = max(ch[1]->rmaxn,ch[1]->sum+v+max(ch[0]->rmaxn,0)); } void* node :: operator new(size_t){ node *p; if(!bin.empty()){ p=bin.back(); bin.pop_back(); } else{ if(C==mempool){ C = new node[1<<15]; mempool = C+(1<<15); } p = C ++; } return p; } void node :: operator delete(void *p){ bin.push_back((node*)p); } pa spilt(node *o,int k){ o->push_down(); if(!k)return make_pair(null,o); if(o==null)return make_pair(null,null); if(k<=o->ch[0]->s){ pa y = spilt(o->ch[0],k); o->ch[0]=y.second; o->Maintain(); y.second=o; return y; } else{ pa y = spilt(o->ch[1],k-o->ch[0]->s-1); o->ch[1]=y.first; o->Maintain(); y.first=o; return y; } } node* merge(node *a,node *b){ a->push_down();b->push_down(); if(a==null)return b; if(b==null)return a; if(a->r>b->r){ a->ch[1]=merge(a->ch[1],b); a->Maintain(); return a; } else{ b->ch[0]=merge(a,b->ch[0]); b->Maintain(); return b; } } int Rank(int x){ node *o=root; int ans = 0; while(o!=null){ if(x<=o->v)o=o->ch[0]; else ans+=o->ch[0]->s+1,o=o->ch[1]; } return ans; } void make_same(int pos,int tot){ int w = read(); pa o = spilt(root,pos-1); pa x = spilt(o.second,tot); change_tag(x.first,w); root = merge(o.first,merge(x.first,x.second)); } void make_filp(int pos,int tot){ if(tot==0)return; pa o = spilt(root,pos-1); pa x = spilt(o.second,tot); change_filp(x.first); node *tmp=merge(x.first,x.second); root = merge(o.first,tmp); } node *build(int l,int r){ if(l>r)return null; int m = l+r>>1; node *p=new node(lst[m]); p->ch[0]=build(l,m-1); p->ch[1]=build(m+1,r); p->Maintain(); return p; } void insert(int pos,int tot){ for(int i=1;i<=tot;i++)scanf("%d",&lst[i]); pa x = spilt(root,pos); root = merge(merge(x.first,build(1,tot)),x.second); } void dfs(node *p){ if(p==null)return; dfs(p->ch[0]); dfs(p->ch[1]); delete p; } void erase(int pos,int tot){ pa x = spilt(root,pos-1); pa y = spilt(x.second,tot); dfs(y.first); root = merge(x.first,y.second); } inline int max_sum(){ if(root==null)return 0; return root->maxn; } inline void sum(int pos,int tot){ if(tot==0){printf("0\n");return;} pa x = spilt(root,pos-1); pa y = spilt(x.second,tot); printf("%d\n",y.first->sum); node *tmp = merge(y.first,y.second); root = merge(x.first,tmp); } void dfs1(node *p){ if(p==null)return; dfs1(p->ch[0]); printf("%d ",p->v); dfs1(p->ch[1]); } int main(){ root = null; n=read(),m=read(); insert(0,n); while(m--){ char opt[10]; scanf("%s",opt); if(opt[0]=='M'){ if(opt[2]=='X')printf("%d\n",max_sum()); else{ int pos = read(),tot = read(); make_same(pos,tot); } continue; } int pos = read(),tot=read(); if(opt[0]=='I')insert(pos,tot); if(opt[0]=='G')sum(pos,tot); if(opt[0]=='D')erase(pos,tot); if(opt[0]=='R')make_filp(pos,tot); } }