关于旋转treap(平衡树)(二叉树)的指针写法

已经很清晰明了

​
#include <stdio.h>
#include <algorithm>
using namespace std;
struct node
{
	int date;
	int cnt=1,siz=1;
	const int rawt=rand();
	node *lf,*rt;
	node(int x){
		date=x;
		lf=rt=NULL;
	}
};
struct treap
{
	protected:
	node *root;
	int siz,u;
	void pu(node *cur)
	{
		if(cur==NULL){return;}
		int temp=cur->cnt;
		temp+=cur->lf==NULL? 0: cur->lf->siz;
		temp+=cur->rt==NULL? 0: cur->rt->siz;
		cur->siz=temp;
	}
	void zig(node *&cur)
	{
		if(cur==NULL){return;}
		node *temp=cur->lf;
		cur->lf=temp->rt;
		temp->rt=cur;
		pu(cur),pu(temp);
		cur=temp;
	}
	void zag(node *&cur)
	{
		if(cur==NULL){return;}
		node *temp=cur->rt;
		cur->rt=temp->lf;
		temp->lf=cur;
		pu(cur),pu(temp);
		cur=temp;
	}
	void insert_sx(int x,node *&cur)
	{
		if(cur==NULL){cur=new node(x);return;}
		if(cur->date==x){cur->cnt++,cur->siz++;}
		else if(cur->date>x)
		{
			insert_sx(x,cur->lf);
			if(cur->lf->rawt<cur->rawt)
			{zig(cur);}
			pu(cur);
		}
		else
		{
			insert_sx(x,cur->rt);
			if(cur->rt->rawt<cur->rawt)
			{zag(cur);}
			pu(cur);
		}
	}
	void eraser_sx(int x,node *&cur)
	{
		if(cur==NULL){return;}
		if(cur->date==x)
		{
			if(cur->cnt>1){cur->cnt--,cur->siz--;return;}
			node *curt=cur,*L=cur->lf,*R=cur->rt;
			int temp=((L!=NULL)<<1)+(R!=NULL);
			switch(temp)
			{
				case 0: delete cur;cur=NULL;break;
				case 1: cur=R; delete curt;break;
				case 2: cur=L; delete curt;break;
				case 3:{
					if(L->rawt<R->rawt)
					{zig(cur);eraser_sx(x,cur->rt);}
					else{zag(cur);eraser_sx(x,cur->lf);}
					pu(cur);
				}
			}
		}
		else if(cur->date>x){eraser_sx(x,cur->lf);pu(cur);}
		else{eraser_sx(x,cur->rt);pu(cur);}
	}
	int valrank_sx(int x,node *cur)
	{
		if(cur==NULL){return 0;}
		if(x<cur->date){return valrank_sx(x,cur->lf);}
		int temp=cur->lf==NULL? 0: cur->lf->siz;
		if(x==cur->date){return temp;}
		return valrank_sx(x,cur->rt)+temp+cur->cnt;
	}
	int rankval_sx(int rk,node *cur)
	{
		if(cur==NULL){return 0;}
		int temp=cur->lf==NULL? 0: cur->lf->siz;
		if(rk<=temp){return rankval_sx(rk,cur->lf);}
		if(rk<=temp+cur->cnt){return cur->date;}
		return rankval_sx(rk-temp-cur->cnt,cur->rt);
	}
	void findlt_sx(int x,node *cur)
	{
		if(cur==NULL){return;}
		if(cur->date<x){u=max(u,cur->date);findlt_sx(x,cur->rt);}
		else{findlt_sx(x,cur->lf);}
	}
	void findnx_sx(int x,node *cur)
	{
		if(cur==NULL){return;}
		if(cur->date>x){u=min(u,cur->date);findnx_sx(x,cur->lf);}
		else{findnx_sx(x,cur->rt);}
	}
	public:
	inline void insert(int x){insert_sx(x,root);}
	inline void eraser(int x){eraser_sx(x,root);}
	inline int valrank(int x){return valrank_sx(x,root)+1;}
	inline int rankval(int rk){return rankval_sx(rk,root);}
	inline int findlt(int x){u=INT_MIN;if(root==NULL){return u;}findlt_sx(x,root);return u;}
	inline int findnx(int x){u=INT_MAX;if(root==NULL){return u;}findnx_sx(x,root);return u;}
}t;
int G,cz,y;
int main() 
{
	scanf("%d",&G);
	while(G--)
	{
		scanf("%d%d",&cz,&y);
		switch(cz)
		{
			case 1: t.insert(y);break;
			case 2: t.eraser(y);break;
			case 3: printf("%d\n",t.valrank(y));break;
			case 4: printf("%d\n",t.rankval(y));break;
			case 5: printf("%d\n",t.findlt(y));break;
			case 6: printf("%d\n",t.findnx(y));break;
		}
	}
	
	
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值