浅谈fhq_treap

class Fhq_Treap{
	private:
	int tot,son[100010][2],key[100010],val[100010],sz[100010];
	inline void updata(int u){
		sz[u]=sz[son[u][0]]+sz[son[u][1]]+1;
	}
	inline void build(int l,int r,int lst){
		if(r<l)
			return ;
		if(l==r){
			son[lst][lst<l]=l;
			key[l]=rand();
			val[l]=l;
			sz[l]=1;
			return ;
		}
		int mid=(l+r)>>1;
		son[lst][lst<mid]=mid;
		key[mid]=rand();
		val[mid]=mid;
		build(l,mid-1,mid);
		build(mid+1,r,mid);
		updata(mid);
	}
	inline void make_rev_tag(int u){
		rev[u]^=1;
		swap(son[u][0],son[u][1]);
	}
	inline void pushdown(int u){
		if(rev[u]){
			if(son[u][0])
				make_rev_tag(son[u][0]);
			if(son[u][1])
				make_rev_tag(son[u][1]);
			rev[u]=0;
		}
	}
	inline pair<int,int>split(int u,int k){
		if(!k)
			return make_pair(0,u);
		if(k==sz[u])
			return make_pair(u,0);
		pushdown(u);
		if(k<=sz[son[u][0]]){
			pair<int,int>res=split(son[u][0],k);
			son[u][0]=res.second;
			updata(u);
			return make_pair(res.first,u);
		}else{
			pair<int,int>res=split(son[u][1],k-sz[son[u][0]]-1);
			son[u][1]=res.first;
			updata(u);
			return make_pair(u,res.second);
		}
	}
	inline int merge(int x,int y){
		if(!x||!y)
			return x+y;
		pushdown(x);
		pushdown(y);
		if(key[x]<key[y]){
			son[x][1]=merge(son[x][1],y);
			updata(x);
			return x;
		}else{
			son[y][0]=merge(x,son[y][0]);
			updata(y);
			return y;
		}
	}
	public:
	int rt;
	bool rev[100010];
	inline void prepare(){
		tot=n;
		rt=(1+n)>>1;
		build(1,n,0);
	}
	inline void rever(int l,int r){
		pair<int,int>spl1=split(rt,r);
		pair<int,int>spl2=split(spl1.first,l-1);
		make_rev_tag(spl2.second);
		rt=merge(merge(spl2.first,spl2.second),spl1.second);
	}
	inline void print_ans(int u){
		if(!u)
			return ;
		pushdown(u);
		print_ans(son[u][0]);
		printf("%d ",val[u]);
		print_ans(son[u][1]);
	}
}F;
posted @ 2018-12-14 17:30  hzf29721  阅读(175)  评论(0编辑  收藏  举报