Orz PoPoQQQ:http://blog.csdn.net/PoPoQQQ/article/details/39430547
边界处理、环状处理完全恶心到我了,已弃疗
我只是一只萌萌哒的代码搬运工……解题报告就不放出来了,太丢人了……
#include <cstdio> #include <cstdlib> #include <climits> #include <cstring> #include <iostream> #include <algorithm> using namespace std; /*WDZRMPCBIT begin typedef struct NODE{ int c,v,s,lc,rc; bool same,rev; NODE *f,*child[2]; NODE(){} NODE(int _v,NODE *_f):v(_v),lc(_v),rc(_v),f(_f){} } *TREE; TREE root,Null; int N,Q,C,a[MAXN]; char s[6+2]; TREE NewNode(int v,TREE f){ TREE x=new NODE(v,f); x->c=x->s=1; x->same=x->rev=0; x->child[0]=x->child[1]=Null; return x; } void Pushup(TREE x){ if(x==Null) return; x->c=x->child[0]->c+x->child[1]->c+1; x->lc=x->rc=x->v; if(x->child[0]!=Null) x->lc=x->child[0]->lc; if(x->child[1]!=Null) x->rc=x->child[1]->rc; x->s=x->child[0]->s+x->child[1]->s; if(x->child[0]!=Null && x->v==x->child[0]->rc) x->s--; if(x->child[1]!=Null && x->v==x->child[1]->lc) x->s--; } void Pushdown(TREE x){ if(x==Null) return; if(x->rev){ x->child[0]->rev^=1,x->child[1]->rev^=1,x->rev=0; if(x->child[0]!=Null){ swap(x->child[0]->child[0],x->child[0]->child[1]); swap(x->child[0]->lc,x->child[0]->rc); } if(x->child[1]!=Null){ swap(x->child[1]->child[0],x->child[1]->child[1]); swap(x->child[1]->lc,x->child[1]->rc); } } if(x->same){ x->same=0; if(x->child[0]!=Null){ x->child[0]->same=1,x->child[0]->v=x->v,x->child[0]->c=1; x->child[0]->lc=x->child[0]->rc=x->v; } if(x->child[1]!=Null){ x->child[1]->same=1,x->child[1]->v=x->v,x->child[1]->c=1; x->child[1]->lc=x->child[1]->rc=x->v; } } } void Initialise(){ Null=NewNode(0,0),Null->c=0; root=NewNode(0,Null); root->child[1]=NewNode(0,root); Null->s=root->s=root->child[1]->s=0; } void Rotate(TREE x,bool t){ TREE y=x->f; Pushdown(x->child[0]),Pushdown(x->child[1]),Pushdown(y->child[t]); y->child[!t]=x->child[t],x->child[t]->f=y,x->f=y->f; if(y->f->child[0]==y) y->f->child[0]=x; else y->f->child[1]=x; y->f=x,x->child[t]=y; Pushup(y),Pushup(x); if(root==y) root=x; } void Splay(TREE x,TREE y){ Pushdown(x); while(x->f!=y) if(x->f->f==y) if(x->f->child[0]==x) Rotate(x,1); else Rotate(x,0); else if(x->f->f->child[0]==x->f) if(x->f->child[0]==x) Rotate(x->f,1),Rotate(x,1); else Rotate(x,0),Rotate(x,1); else if(x->f->child[0]==x) Rotate(x,1),Rotate(x,0); else Rotate(x->f,0),Rotate(x,0); } void Select(int p,TREE y){ TREE x=root;Pushdown(x); while(p!=x->child[0]->c+1){ if(p<=x->child[0]->c) x=x->child[0]; else p-=x->child[0]->c+1,x=x->child[1]; Pushdown(x); } Splay(x,y); } void Visit(TREE x){ if(x==Null) return; Visit(x->child[0]); cout << x->c << " " << x->s << " " << x->lc << " " << x->rc << endl; Visit(x->child[1]); } void Insert(int p,int n,int *a){ TREE s,t; s=t=NewNode(a[1],Null); for(int i=2;i<=n;i++) t=t->child[1]=NewNode(a[i],t); Select(p+1,Null),Select(p+2,root); root->child[1]->child[0]=s,s->f=root->child[1]; Splay(t,Null); Visit(root); } void Reverse(int p,int n){ Select(p,Null),Select(p+n+1,root); root->child[1]->child[0]->rev^=1; Splay(root->child[1]->child[0],Null); } void Change(int p,int n,int v){ Select(p,Null),Select(p+n+1,root); root->child[1]->child[0]->same=1,root->child[1]->child[0]->v=v; Splay(root->child[1]->child[0],Null); } void Move(int p,int n){ Select(p+1,Null),Select(p+n+2,root); TREE x=root->child[1]->child[0]; root->child[1]->child[0]=Null; Pushup(root->child[1]),Pushup(root); Select(1,Null),Select(2,root); root->child[1]->child[0]=x,x->f=x->child[1]; Pushup(root->child[1]),Pushup(root); } void Swap(int a,int b){ Select(a,Null),Select(b,root); int v=root->v; Change(a,1,root->child[1]->v),Change(b,1,v); } int Query_Total(){ Selct(1,Null),Select(N+2,root); TREE x=root->child[1]->child[0]; return max(1,x->s-(x->lc==x->rc)); } int Query_Part(int a,int b){ if(a<=b){ Select(a,Null),Select(b+2,root); return x->child[1]->child[0]->s; } Select(a,Null),Select(N+2,root); int ret=root->child[1]->child[0]->s,c=root->child[1]->child[0]->rc; Select(1,Null),Select(b+2,root); return ret+root->child[1]->child[0]->s-(c==root->child[1]->child[0]->lc); } WDZRMPCBIT end*/ //PoPoQQQ begin struct color_segment{ int cnt,lcolor,rcolor; color_segment(int x){ cnt=(!x?0:1); lcolor=rcolor=x; } }; color_segment operator + (const color_segment x,const color_segment y) { color_segment re(0); re.lcolor=x.lcolor?x.lcolor:y.lcolor; re.rcolor=y.rcolor?y.rcolor:x.rcolor; re.cnt=x.cnt+y.cnt-(x.rcolor==y.lcolor); return re; } struct NODE{ int num,siz; NODE *fa,*ls,*rs; color_segment *s; int rev_mark,change_mark; NODE(int x); void Push_Up(); void Push_Down(); }*null=new NODE(0),*root=null; int N,M,C; char p[10]; NODE::NODE(int x){ num=x,siz=1; if(!x) siz=0; fa=ls=rs=null; rev_mark=change_mark=0; s=new color_segment(x); } void NODE::Push_Up(){ siz=ls->siz+rs->siz+1; *s=(*ls->s)+color_segment(num)+(*rs->s); } void NODE::Push_Down(){ if(rev_mark){ ls->rev_mark^=1,rs->rev_mark^=1; swap(ls->ls,ls->rs),swap(rs->ls,rs->rs); swap(ls->s->lcolor,ls->s->rcolor),swap(rs->s->lcolor,rs->s->rcolor); rev_mark=0; } if(change_mark){ if(ls!=null){ ls->num=ls->change_mark=change_mark; *ls->s=color_segment(change_mark); } if(rs!=null){ rs->num=rs->change_mark=change_mark; *rs->s=color_segment(change_mark); } change_mark=0; } } void Zig(NODE *x) { NODE *y=x->fa; y->Push_Down(); x->Push_Down(); y->ls=x->rs; x->rs->fa=y; x->rs=y; x->fa=y->fa; if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->Push_Up(); if(y==root) root=x; } void Zag(NODE *x) { NODE *y=x->fa; y->Push_Down(); x->Push_Down(); y->rs=x->ls; x->ls->fa=y; x->ls=y; x->fa=y->fa; if(y==y->fa->ls) y->fa->ls=x; else if(y==y->fa->rs) y->fa->rs=x; y->fa=x; y->Push_Up(); if(y==root) root=x; } void Splay(NODE *x,NODE *Tar) { while(1) { NODE *y=x->fa,*z=y->fa; if(y==Tar) break; if(z==Tar) { if(x==y->ls) Zig(x); else Zag(x); break; } if(x==y->ls) { if(y==z->ls) Zig(y); Zig(x); } else { if(y==z->rs) Zag(y); Zag(x); } } x->Push_Up(); } void Find(NODE *x,int y,NODE *z){ while(1){ x->Push_Down(); if(y<=x->ls->siz) x=x->ls; else{ y-=x->ls->siz; if(y==1) break; y--,x=x->rs; } } Splay(x,z); } void Insert(NODE *&x,int y,NODE *z){ if(x==null){ x=new NODE(y); x->fa=z; Splay(x,null); return; } x->Push_Down(); Insert(x->rs,y,x); } int main(){ cin >> N >> C; Insert(root,INT_MAX,null); for(int i=1,x;i<=N;i++) scanf("%d",&x),Insert(root,x,null); Insert(root,INT_MAX,null); cin >> M; for(int i=1,x,y,z;i<=M;i++){ scanf("%s",p); if(p[0]=='R'){ scanf("%d",&x); Find(root,N-x+1,null),Find(root,N+2,root); NODE *temp=root->rs->ls; root->rs->ls=null,root->rs->Push_Up(); root->Push_Up(); Find(root,1,null),Find(root,2,root); root->rs->ls=temp; temp->fa=root->rs; root->rs->Push_Up(); root->Push_Up(); } else if(p[0]=='F'){ Find(root,2,null),Find(root,N+2,root); NODE *temp=root->rs->ls; temp->rev_mark^=1; swap(temp->ls,temp->rs),swap(temp->s->lcolor,temp->s->rcolor); } else if(p[0]=='S'){ scanf("%d%d",&x,&y); if(x==y) continue; if(x>y) swap(x,y); Find(root,x+1,null),Find(root,y+1,root); swap(root->rs->num,root->num); root->rs->Push_Up(),root->Push_Up(); } else if(p[0]=='P'){ scanf("%d%d%d",&x,&y,&z); if(x<=y){ Find(root,x,null),Find(root,y+2,root); NODE *temp=root->rs->ls; temp->num=temp->change_mark=z; *temp->s=color_segment(z); } else{ Find(root,x,null),Find(root,N+2,root); NODE *temp=root->rs->ls; temp->num=temp->change_mark=z; *temp->s=color_segment(z); Find(root,1,null),Find(root,y+2,root); temp=root->rs->ls; temp->num=temp->change_mark=z; *temp->s=color_segment(z); } } else if(p[0]=='C'&&p[1]==0){ Find(root,1,null),Find(root,N+2,root); NODE *temp=root->rs->ls; printf("%d\n",max(1,temp->s->cnt-(temp->s->lcolor==temp->s->rcolor))); } else{ scanf("%d%d",&x,&y); if(x<=y){ Find(root,x,null),Find(root,y+2,root); NODE *temp=root->rs->ls; printf("%d\n",temp->s->cnt); } else{ Find(root,x,null),Find(root,N+2,root); NODE *temp=root->rs->ls; color_segment s=*temp->s; Find(root,1,null),Find(root,y+2,root); temp=root->rs->ls,s=s+*temp->s; printf("%d\n",s.cnt); } } } return 0; } //PoPoQQQ end