【模板】普通平衡树

题目链接

        Treap平衡树,模板题,无题解。

Code:

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
template<typename T> void read(T &num){
	char c=getchar();num=0;T f=1;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){num=(num<<3)+(num<<1)+(c^48);c=getchar();}
	num*=f;
}
template<typename T> void qwq(T x){
	if(x>9)qwq(x/10);
	putchar(x%10+'0');
}
template<typename T> void write(T x){
	if(x<0){x=-x;putchar('-');}
	qwq(x);putchar('\n');
}
struct wzy{
	int ls,rs,val,pri,cnt,siz;
}tree[100010];
int tot=0;int root=0;
inline void Zig(int &pos){//you
	int temp=tree[pos].ls;
	tree[pos].ls=tree[temp].rs;tree[temp].rs=pos;
	tree[temp].siz=tree[pos].siz;
	tree[pos].siz=tree[tree[pos].ls].siz+tree[tree[pos].rs].siz+tree[pos].cnt;
	pos=temp;return;
}
inline void Zag(int &pos){//zuo
	int temp=tree[pos].rs;
	tree[pos].rs=tree[temp].ls;tree[temp].ls=pos;
	tree[temp].siz=tree[pos].siz;
	tree[pos].siz=tree[tree[pos].ls].siz+tree[tree[pos].rs].siz+tree[pos].cnt;
	pos=temp;return;
}
inline void Change(int &pos,int w){
	if(!pos){
		pos=++tot;tree[pos].val=w;tree[pos].pri=rand();
		tree[pos].cnt=tree[pos].siz=1;tree[pos].ls=tree[pos].rs=0;return;
	}else{tree[pos].siz++;}
	
	if(tree[pos].val==w){tree[pos].cnt++;}
	else if(tree[pos].val>w){
		Change(tree[pos].ls,w);
		if(tree[tree[pos].ls].pri<tree[pos].pri)Zig(pos);	
	}else{
		Change(tree[pos].rs,w);
		if(tree[tree[pos].rs].pri<tree[pos].pri)Zag(pos);
	}
	return;
}
inline void Del(int &pos,int w){
	if(tree[pos].val==w){
		if(tree[pos].cnt>1){tree[pos].cnt--;tree[pos].siz--;return;}
		if(!tree[pos].ls||!tree[pos].rs){pos=tree[pos].ls+tree[pos].rs;}
		else if(tree[tree[pos].ls].pri<tree[tree[pos].rs].pri){Zig(pos);Del(pos,w);}
		else{Zag(pos);Del(pos,w);}
		return;
	}
	tree[pos].siz--;
	if(w<tree[pos].val){Del(tree[pos].ls,w);}
	else{Del(tree[pos].rs,w);}
	return;
}
inline int Quernk(int w){
	int x=root;int ret=0;
	while(x){
		if(tree[x].val==w){return (ret+tree[tree[x].ls].siz+1);}
		else if(tree[x].val>w){x=tree[x].ls;}
		else{ret+=tree[tree[x].ls].siz+tree[x].cnt;x=tree[x].rs;}
	}
	return ret;
}
inline int Quekth(int k){
	int x=root;
	while(x){
		if(tree[tree[x].ls].siz+1<=k&&k<=tree[tree[x].ls].siz+tree[x].cnt){return tree[x].val;}
		else if(k<tree[tree[x].ls].siz+1){x=tree[x].ls;}
		else{k-=tree[tree[x].ls].siz+tree[x].cnt;x=tree[x].rs;}
	}
	return 0;
}
inline int Quepre(int w){
	int x=root;int ret=-INT_MAX;
	while(x){
		if(tree[x].val<w){ret=tree[x].val;x=tree[x].rs;}
		else{x=tree[x].ls;}
	}
	return ret;
}
inline int Quesuf(int w){
	int x=root;int ret=INT_MAX;
	while(x){
		if(tree[x].val>w){ret=tree[x].val;x=tree[x].ls;}
		else{x=tree[x].rs;}
	}
	return ret;
}

int main(){
	srand(time(NULL));
	int n;read(n);
	rep(i,1,n){
		int opt,x;read(opt);read(x);
		if(opt==1){
			Change(root,x);
		}else if(opt==2){
			Del(root,x);
		}else if(opt==3){
			write(Quernk(x));
		}else if(opt==4){
			write(Quekth(x));
		}else if(opt==5){
			write(Quepre(x));
		}else{
			write(Quesuf(x));
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值