传送门: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);
}else
if(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;
}