Splay模版题
调试两天总算A啦!
2016/2/21 *1
2016/3/20 *1
#include<cstdio> #include<algorithm> using namespace std; int n,a[1000005],m; struct Node{ int v,mx,sum,lx,rx,siz,tag,rev; Node *ch[2],*fa; Node(int val,Node *fat); void Pushdown(); void Pushup(); }*root,*Null; Node::Node(int val=0,Node *fat=Null){ ch[0]=ch[1]=Null; fa=fat; v=sum=mx=val; tag=rev=0; siz=1; if(v>=0)lx=rx=v; else lx=rx=0; } void Node::Pushdown(){ if(tag){ tag=rev=0; if(ch[0]!=Null){ch[0]->tag=1;ch[0]->sum=ch[0]->siz*v;ch[0]->v=v;} if(ch[1]!=Null){ch[1]->tag=1;ch[1]->sum=ch[1]->siz*v;ch[1]->v=v;} if(v>=0){ if(ch[0]!=Null){ch[0]->lx=ch[0]->mx=ch[0]->rx=v*ch[0]->siz;} if(ch[1]!=Null){ch[1]->lx=ch[1]->mx=ch[1]->rx=v*ch[1]->siz;} } else { if(ch[0]!=Null){ch[0]->mx=v;ch[0]->lx=ch[0]->rx=0;} if(ch[1]!=Null){ch[1]->mx=v;ch[1]->lx=ch[1]->rx=0;} } } if(rev){ rev=0; if(ch[0]!=Null)ch[0]->rev^=1; if(ch[1]!=Null)ch[1]->rev^=1; swap(ch[0]->ch[0],ch[0]->ch[1]); swap(ch[1]->ch[0],ch[1]->ch[1]); swap(ch[0]->lx,ch[0]->rx); swap(ch[1]->lx,ch[1]->rx); } } void Node::Pushup(){ siz=ch[0]->siz+ch[1]->siz+1; sum=ch[0]->sum+ch[1]->sum+v; mx=max(ch[0]->mx,ch[1]->mx); mx=max(mx,ch[0]->rx+v+ch[1]->lx); lx=max(ch[0]->lx,ch[0]->sum+v+ch[1]->lx); rx=max(ch[1]->rx,ch[1]->sum+v+ch[0]->rx); } void Rotate(Node *x,int kind){ Node *y=x->fa,*z=y->fa; y->ch[!kind]=x->ch[kind]; if(x->ch[kind]!=Null)x->ch[kind]->fa=y; x->fa=z; if(z!=Null)z->ch[z->ch[1]==y]=x; y->fa=x; x->ch[kind]=y; y->Pushup(); x->Pushup(); } void Splay(Node *x,Node *place){ while(x->fa!=place){ Node *y=x->fa,*z=y->fa; if(z==Null || z==place)Rotate(x,y->ch[0]==x); else { if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);} else if(y->ch[0]==x && z->ch[1]==y){Rotate(x,1);Rotate(x,0);} else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);} else {Rotate(y,0);Rotate(x,0);} } } if(place==Null)root=x; } Node *Find(Node *splay,int k){ splay->Pushdown(); if(splay->ch[0]->siz+1==k)return splay; if(splay->ch[0]->siz>=k)return Find(splay->ch[0],k); return Find(splay->ch[1],k-1-splay->ch[0]->siz); } Node *Split(int pos,int tot){ Node *x=Find(root,pos); Splay(x,Null); Node *y=Find(root,pos+tot+1); Splay(y,root); return y->ch[0]; } Node *Build(int l,int r){ if(l>r)return Null; int mid=l+r>>1; Node *splay=new Node(a[mid],Null); splay->ch[0]=Build(l,mid-1); if(splay->ch[0]!=Null)splay->ch[0]->fa=splay; splay->ch[1]=Build(mid+1,r); if(splay->ch[1]!=Null)splay->ch[1]->fa=splay; splay->Pushup(); return splay; } void Insert(int pos,int tot){ Node *x=Find(root,pos+1),*y=Find(root,pos+2); Splay(x,Null);Splay(y,root); y->ch[0]=Build(1,tot); if(y->ch[0]!=Null)y->ch[0]->fa=y; y->Pushup(); x->Pushup(); } Node *GetNull(){ Node *p=new Node(0,Null); p->fa=p->ch[0]=p->ch[1]=p; p->mx=p->v=-1000000000; p->rev=p->tag=p->siz=p->sum=p->lx=p->rx=0; return p; } void Build_First(){ Null=GetNull(); a[1]=-1000000000; a[n+2]=-1000000000; root=Build(1,n+2); } void Del_Tree(Node *splay){ if(splay==Null)return; splay->Pushdown(); Del_Tree(splay->ch[0]); Del_Tree(splay->ch[1]); if(splay->ch[0]!=Null)delete splay->ch[0]; if(splay->ch[1]!=Null)delete splay->ch[1]; splay->ch[0]=Null; splay->ch[1]=Null; splay->Pushup(); } void Delete(int pos,int val){ Node *seq=Split(pos,val),*fat=seq->fa; Del_Tree(seq); if(seq!=Null)delete seq; fat->ch[0]=Null; fat->Pushup(); fat->fa->Pushup(); } void MakeSame(int pos,int tot,int val){ Node *seq=Split(pos,tot),*fat=seq->fa; seq->tag=1; seq->sum=seq->siz*val; seq->v=val; if(val>=0)seq->lx=seq->rx=seq->mx=seq->siz*val; else seq->lx=seq->rx=0,seq->mx=val; fat->Pushup(); fat->fa->Pushup(); } void Reverse(int pos,int tot){ Node *seq=Split(pos,tot),*fat=seq->fa; if(!seq->tag){ seq->rev^=1; swap(seq->ch[0],seq->ch[1]); swap(seq->lx,seq->rx); fat->Pushup(); fat->fa->Pushup(); } } int GetSum(int pos,int tot){ Node *seq=Split(pos,tot); return seq->sum; } int main(){ freopen("1500.in","r",stdin); freopen("1500.out","w",stdout); scanf("%d %d",&n,&m); for(int i=2;i<=n+1;i++)scanf("%d",&a[i]); Build_First(); for(int i=1;i<=m;i++){ char s[10]; scanf("%s",s); if(s[0]=='I'){ int pos,tot; scanf("%d %d",&pos,&tot); for(int i=1;i<=tot;i++)scanf("%d",&a[i]); Insert(pos,tot); } if(s[0]=='D'){ int pos,tot; scanf("%d %d",&pos,&tot); Delete(pos,tot); } if(s[0]=='M' && s[2]=='K'){ int pos,tot,val; scanf("%d %d %d",&pos,&tot,&val); MakeSame(pos,tot,val); } if(s[0]=='M' && s[2]=='X'){ printf("%d\n",root->mx); } if(s[0]=='R'){ int pos,tot; scanf("%d %d",&pos,&tot); Reverse(pos,tot); } if(s[0]=='G'){ int pos,tot; scanf("%d %d",&pos,&tot); printf("%d\n",GetSum(pos,tot)); } } return 0; }