【BZOJ】【P1493】【NOI2007】【项链工厂】【题解】【Treap】

来源:互联网 发布:keep健身软件好用吗 编辑:程序博客网 时间:2024/05/17 03:52

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1493

还以为fhpTreap会T出翔,然后7s+A了……

直接平衡树维护就行了

Code:

#include<bits/stdc++.h>using namespace std;int n,m,c;int getint(){int res=0;char c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))res=res*10+c-'0',c=getchar();return res;}struct color{int x,y,z;color(int _col=0){x=z=_col;y=bool(_col);}};color operator+(color a,color b){if(!a.y)return b;if(!b.y)return a;color ans;ans.x=a.x;ans.z=b.z;ans.y=a.y+b.y-(a.z==b.x);return ans;}struct node;node *Null;struct node{int key,col;color co;int rev,lazy,size;node *c[2];node(int _col=0,node *C=0){key=rand();col=_col;co=color(_col);rev=lazy=0;c[0]=c[1]=C;size=1;}node *rz(){size=c[0]->size+1+c[1]->size;co=c[0]->co+color(col)+c[1]->co;return this;}node *makerev(){rev^=1;swap(c[0],c[1]);swap(co.x,co.z);return this;}node *makesame(int _col){lazy=col=_col;co=color(_col);return this;}void pushrev(){if(rev){if(c[0]!=Null)c[0]->makerev();if(c[1]!=Null)c[1]->makerev();rev^=1;}}void pushsame(){if(lazy){if(c[0]!=Null)c[0]->makesame(lazy);if(c[1]!=Null)c[1]->makesame(lazy);lazy=0;}}void pushdown(){pushrev();pushsame();}void split(int ned,node *&p,node *&q);}*root;node *merge(node *p,node *q){if(p==Null)return q;if(q==Null)return p;q->pushdown();p->pushdown();if(p->key<q->key){p->c[1]=merge(p->c[1],q);return p->rz();}else{q->c[0]=merge(p,q->c[0]);return q->rz();}}void node::split(int ned,node *&p,node *&q){if(this==Null)return void(p=q=Null);pushdown();if(c[0]->size>=ned){c[0]->split(ned,p,q);c[0]=Null;rz();q=merge(q,this);}else{c[1]->split(ned-c[0]->size-1,p,q);c[1]=Null;rz();p=merge(this,p);}}node *p,*q,*r,*s;void R(int x){root->split(n-x,p,q);root=merge(q,p);}void F(){root->split(1,p,q);q->makerev();root=merge(p,q);}void S(int L,int R){if(L==R)return;if(L>R)swap(L,R);int a,b;node *x,*y,*z,*w;root->split(L-1,p,q);q->split(1,r,s);s->split(R-L-1,x,y);y->split(1,z,w);swap(r->col,z->col);r->rz();z->rz();root=merge(p,merge(r,merge(x,merge(z,w))));}void P(int L,int R,int x){if(L<=R){root->split(L-1,p,q);q->split(R-L+1,r,s);r->makesame(x);root=merge(p,merge(r,s));}else{root->split(R,p,q);q->split(L-R-1,r,s);p->makesame(x);s->makesame(x);root=merge(p,merge(r,s));}}void C(){printf("%d\n",max(root->co.y-(root->co.x==root->co.z),1));}void CS(int L,int R){if(L<=R){root->split(L-1,p,q);q->split(R-L+1,r,s);printf("%d\n",r->co.y);root=merge(p,merge(r,s));}else{root->split(R,p,q);q->split(L-R-1,r,s);printf("%d\n",(s->co+p->co).y);root=merge(p,merge(r,s));}}int main(){Null=new node(0,0);Null->size=0;Null->key=INT_MAX;Null->c[0]=Null->c[1]=Null;root=Null;n=getint();c=getint();for(int i=1;i<=n;i++)root=merge(root,new node(getint(),Null));m=getint();while(m--){char op[5];scanf("%s",op);int l,r,x;if(op[0]=='R'){R(getint());}else if(op[0]=='F'){F();}else if(op[0]=='S'){l=getint();r=getint();S(l,r);}elseif(op[0]=='P'){l=getint();r=getint();x=getint();P(l,r,x);}else if(strlen(op)==1){C();}else{l=getint();r=getint();CS(l,r);}}return 0;}


0 0