1. 程式人生 > 其它 >平衡樹板子

平衡樹板子

Treap

code
struct Treap{
	struct node{
		int l,r,val,key,siz,cnt;
	}t[maxn];
	int tot,root;

	int New(int x){
		t[++tot].val=x;
		t[tot].key=rand();
		t[tot].siz=t[tot].cnt=1;
		return tot;
	}

	void push_up(int x){t[x].siz=t[t[x].l].siz+t[t[x].r].siz+t[x].cnt;}

	void zig(int &x){
		int y=t[x].l;
		t[x].l=t[y].r;
		t[y].r=x;
		x=y;
		push_up(t[x].r);
		push_up(x);
	}

	void zag(int &x){
		int y=t[x].r;
		t[x].r=t[y].l;
		t[y].l=x;
		x=y;
		push_up(t[x].l);
		push_up(x);
	}

	void insert(int &x,int val){
		if(x==0)return x=New(val),void();
		if(t[x].val==val)return ++t[x].cnt,++t[x].siz,void();
		if(val<t[x].val){
			insert(t[x].l,val);
			push_up(x);
			if(t[x].key<t[t[x].l].key)return zig(x);
		}
		if(val>t[x].val){
			insert(t[x].r,val);
			push_up(x);
			if(t[x].key<t[t[x].r].key)return zag(x);
		}
	}

	void erase(int &x,int val){
		if(x==0)return;
		if(t[x].val==val){
			if(t[x].cnt>1)return --t[x].cnt,--t[x].siz,void();
			if(!t[x].l&&!t[x].r)return x=0,void();
			if(!t[x].r||t[t[x].l].key>t[t[x].r].key)return zig(x),erase(t[x].r,val),push_up(x);
			if(!t[x].l||t[t[x].l].key<t[t[x].r].key)return zag(x),erase(t[x].l,val),push_up(x);
		}
		if(val<t[x].val)erase(t[x].l,val);
		else erase(t[x].r,val);
		push_up(x);
	}

	int rank(int x,int val){
		if(x==0)return 0;
		if(t[x].val==val)return t[t[x].l].siz;
		if(t[x].val<val)return rank(t[x].r,val)+t[t[x].l].siz+t[x].cnt;
		else return rank(t[x].l,val);
	}

	int pre(int val){
		int x=root,ans=-2147483645;
		while(x){
			if(t[x].val<val)ans=max(ans,t[x].val),x=t[x].r;
			else x=t[x].l;
		}
		return ans;
	}

	int next(int val){
		int x=root,ans=2147483647;
		while(x){
			if(t[x].val>val)ans=min(ans,t[x].val),x=t[x].l;
			else x=t[x].r;
		}
		return ans;
	}
	
	int kth(int x,int th){
		if(th<=t[t[x].l].siz)return kth(t[x].l,th);
		if(th<=t[t[x].l].siz+t[x].cnt)return t[x].val;
		return kth(t[x].r,th-t[t[x].l].siz-t[x].cnt);
	}
}T;

FHQ_Treap

code
struct FHQ_Treap{
	struct node{
		int l,r,size,val,key;
	}t[maxn];
	int tot,root;
	int New(int x){t[++tot].val=x;t[tot].key=rand();t[tot].size=1;return tot;}
	void push_up(int x){t[x].size=t[t[x].l].size+t[t[x].r].size+1;}
	void split(int x,int &rtx,int &rty,int val){
		if(x==0)return rtx=rty=0,void();
		if(val<t[x].val){split(t[x].l,rtx,t[x].l,val);rty=x;push_up(rty);return;}
		else{split(t[x].r,t[x].r,rty,val);rtx=x;push_up(rtx);return;}
	}
	int merge(int x,int y){
		if(!x||!y)return x|y;
		if(t[x].key<t[y].key){t[x].r=merge(t[x].r,y);push_up(x);return x;}
		else{t[y].l=merge(x,t[y].l);push_up(y);return y;}
	}
	void insert(int x){
		int l=0,r=0;split(root,l,r,x);
		root=merge(merge(l,New(x)),r);
	}
	void erase(int x){
		int l,m,r;split(root,l,r,x);split(l,l,m,x-1);
		m=merge(t[m].l,t[m].r);
		root=merge(merge(l,m),r);
	}
	int kth(int x,int id){
		if(t[t[x].l].size+1==id)return t[x].val;
		if(t[t[x].l].size>=id)return kth(t[x].l,id);
		return kth(t[x].r,id-t[t[x].l].size-1);
	}
	int rank(int x){
		int l=0,r=0,ans=0;
		split(root,l,r,x-1);
		ans=t[l].size+1;
		root=merge(l,r);
		return ans;
	}
	int pre(int x){
		int l=0,r=0,ans=0;
		split(root,l,r,x-1);
		ans=kth(l,t[l].size);
		root=merge(l,r);
		return ans;
	}
	int nxt(int x){
		int l=0,r=0,ans=0;
		split(root,l,r,x);
		ans=kth(r,1);
		root=merge(l,r);
		return ans;
	}
}T;