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

传送门: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;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值