【BZOJ】【P3223】【文艺平衡树】【题解】

传送门:

http://www.lydsy.com/JudgeOnline/problem.php?id=3223

传说中的可持久化Treap?写了一下午……附赠一大坨调试信息

Code:

/*
	ID:zky
	OJ:BZOJ
	Index:3223
	Language:C++
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<climits>
#include<cstdlib>
using namespace std;
int rnd(){
	static int KEY=12345678;
	return KEY+=KEY<<2|1;
}
struct node;
node *Null,*root;
struct node{
	int val,size,key,lazy;
	node *c[2];
	void split(int need,node *&p,node *&q);
	node(int _val,node *C){
		val=_val;size=1;
		key=rnd();lazy=0;
		c[0]=c[1]=C;
	}
	void rev(){
		if(this==Null)return;
		lazy^=1;
		swap(c[0],c[1]);
	}
	node* rz(){
		size=c[0]->size+c[1]->size+1;
		return this;
	}
	void pushdown(){
		if(lazy){
			c[0]->rev();
			c[1]->rev();
			lazy=0;
		}
	}
};
node *merge(node *p,node *q){
	if(p==Null)return q->rz();
	if(q==Null)return p->rz();
	if(p->key<q->key){
		p->pushdown();
		p->c[1]=merge(p->c[1],q);
		return p->rz();
	}else{
		q->pushdown();
		q->c[0]=merge(p,q->c[0]);
		return q->rz();
	}
}
void deb(node *t){
	printf("val:%d L:%d R:%d lazy:%d size:%d\n",
	t->val,t->c[0]->val,t->c[1]->val,t->lazy,t->size);
	if(t->c[0]!=Null)
	deb(t->c[0]);
	if(t->c[1]!=Null)
	deb(t->c[1]);
}
void node::split(int need,node *&p,node *&q){
	if(this==Null){p=Null;q=Null;return;}
	pushdown();
	//deb(this);cout<<endl;
	if(c[0]->size>=need){
		c[0]->split(need,p,q);
		c[0]=Null;
		rz();
		q=merge(q,this);
	//	deb(q);cout<<endl;
		return;
	}else{
		c[1]->split(need-c[0]->size-1,p,q);
		c[1]=Null;
		pushdown();
		p=merge(this,p);
	//	deb(p);cout<<endl;
		return;
	}
}
struct Treap{	
	Treap(){
		Null=new node(0,0);
		Null->size=0;
		Null->c[0]=Null->c[1]=Null;
		Null->key=INT_MAX;
		root=Null;
	}
	void rev(int a,int b){
		node *p,*q,*r,*s;
		root->split(a-1,p,q);
		
	//	deb(p);
	//	cout<<endl;
	//	deb(q);
	//	cout<<endl;
		
		q->split(b-a+1,r,s);
		
	//	deb(r);
	//	cout<<endl;
	//	deb(s);
	//	cout<<endl;
				
		r->rev();
		
		
		
		root=merge(p,merge(r,s));
		root->rz();
	}
	void print(node *t){
		t->pushdown();
		if(t->c[0]!=Null)
		print(t->c[0]);
		printf("%d ",t->val);
		if(t->c[1]!=Null)
		print(t->c[1]);
	}
	void deb(node *t){
		printf("val:%d L:%d R:%d lazy:%d size:%d\n",
		t->val,t->c[0]->val,t->c[1]->val,t->lazy,t->size);
		if(t->c[0]!=Null)
		deb(t->c[0]);
		if(t->c[1]!=Null)
		deb(t->c[1]);
	}
}T;
node* newnode(int c)
{
    node* x=new node(c,Null);
    return x;
}
int n,m;
int main(){
//	freopen("1.txt","r",stdin);
//	freopen("3.txt","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		root=merge(root,newnode(i));
	}
	//T.deb(root);
	//cout<<endl;
	while(m--){
		int a,b;
		scanf("%d%d",&a,&b);
		if(a>b)swap(a,b);
		//b=b-a+1;
		T.rev(a,b);
	//	T.deb(root);
	//	cout<<endl;
	}
	T.print(root);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值