【Treap模板】

本文介绍了一种平衡树——Treap的数据结构实现方法。Treap结合了二叉搜索树和堆的特点,支持快速插入、删除等操作,并提供了如查找第k小元素等功能。通过本文,读者可以了解Treap的基本原理及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好久没写平衡树手生了

重打一遍Treap

#include<bits/stdc++.h>
using namespace std;
struct Treap{
	struct node{
		int val,key,size,s;
		node *c[2];
		node(int _val=0,node *C=0){
			val=_val;key=rand();
			size=s=1;c[0]=c[1]=C;
		}void rz(){
			size=c[0]->size+s+c[1]->size;
		}
	}*root,*Null;
	Treap(){
		Null=new node(0,0);
		Null->size=Null->s=0;Null->key=INT_MAX;
		Null->c[0]=Null->c[1]=Null;root=Null;
	}
	void rot(node *&t,bool d){
		node *p=t->c[d];t->c[d]=p->c[!d];
		p->c[!d]=t;t->rz();p->rz();t=p;
	}
	void _insert(node *&t,int x){
		if(t==Null){t=new node(x,Null);return;}
		if(t->val==x){t->s++;t->size++;return;}
		_insert(t->c[x>t->val],x);
		if(t->c[x>t->val]->key<t->key)
		rot(t,x>t->val);else t->rz();
	}
	void _del(node *&t,int x){
		if(t->val==x){
			if(t->s>1){t->s--;t->size--;return;}
			bool d=t->c[0]->key>t->c[1]->key;
			if(t->c[d]==Null){delete t;t=Null;return;}	
			rot(t,d);_del(t->c[!d],x);
		}else _del(t->c[x>t->val],x);t->rz();
	}
	int _kth(node *t,int x){
		int r=t->c[0]->size;
		if(x<=r)return _kth(t->c[0],x);
		else if(x>r+t->s) return _kth(t->c[1],x-r-t->s);
		return t->val;
	}
	int _rank(node *t,int x){
		int r=t->c[0]->size;
		if(x<t->val)return _rank(t->c[0],x);
		else if(x>t->val)return _rank(t->c[1],x)+r+t->s;
		return r;
	}
	int _prev(node *t,int x){
		if(t==Null)return INT_MIN;
		if(x<=t->val)return _prev(t->c[0],x);
		return max(t->val,_prev(t->c[1],x));
	}
	int _next(node *t,int x){
		if(t==Null)return INT_MAX;
		if(x>=t->val)return _next(t->c[1],x);
		return min(t->val,_next(t->c[0],x));
	}
	void insert(int x){_insert(root,x);}
	void del(int x){_del(root,x);}
	int kth(int x){return _kth(root,x);}
	int rank(int x){return _rank(root,x);}
	int prev(int x){return _prev(root,x);}
	int next(int x){return _next(root,x);}
}T;
int main(){  
    srand(12121);  
    int n,m;  
    scanf("%d",&n);m=n;  
    while(n--){  
        int opt,x;  
        scanf("%d",&opt);  
        switch(opt){  
            case 1:  
                scanf("%d",&x);  
                T.insert(x);  
                break;  
            case 2:  
                scanf("%d",&x);  
                T.del(x);  
                break;  
            case 3:  
                scanf("%d",&x);  
                printf("%d\n",T.rank(x)+1);  
                break;  
            case 4:               
                scanf("%d",&x);  
                printf("%d\n",T.kth(x));  
                break;  
            case 5:  
                scanf("%d",&x);  
                printf("%d\n",T.prev(x));  
                break;  
            case 6:  
                scanf("%d",&x);  
                printf("%d\n",T.next(x));  
                break;    
        }  
    }  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值