不基于旋转的Treap(仅代码)

本文介绍了一种使用Treap(一种随机化的二叉搜索树)的数据结构实现方法,并通过具体的C++代码示例展示了如何进行插入、删除、查找排名等操作。适用于需要高效处理动态集合问题的场景。

日常安利大佬博客.
然后我并不想写东西
正常代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<ctime>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<algorithm>
#include<cstdlib>
#define LL long long
using namespace std;
const int N=50005;
struct Treap {
    int ch[2],val,siz,cnt,prio;//ls ch[0],rs ch[1]
} t[N<<5];
int ncnt,n,opt,p,rt,tot,sz;
//rd[30]= {18333,29820,10757,21866,11757,6209,12761,32459,8312,24791,12980,15005,18195,7950,8507,13765,15014,27005,21944,21302,20191,3945,17258,22014,9256,13032,14880,27782,5591};
void newnode(int &x,int k){
    t[++tot].val=k;
    t[tot].prio=rand();
    t[tot].cnt=t[tot].siz=1;
    x=tot;
}
void update(int x){
    t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+1;
}
void merge(int &k,int a,int b){
    if(!a||!b){
        k=a+b;
        return;
    }
    if(t[a].prio<t[b].prio) k=a,merge(t[k].ch[1],t[a].ch[1],b);
    else k=b,merge(t[k].ch[0],a,t[b].ch[0]);
    update(k);
}
void split(int k,int &tl,int &tr,int val){
    if(!k){tl=tr=0;return;}
    if(t[k].val<=val)tl=k,split(t[k].ch[1],t[tl].ch[1],tr,val);
    else tr=k,split(t[k].ch[0],tl,t[tr].ch[0],val);
    update(k);
}
void insert(int val){
    int x=0,y=0,z=0;
    newnode(z,val);
    split(rt,x,y,val);
    merge(x,x,z);
    merge(rt,x,y);
}
void del(int val){
    int x=0,y=0,z=0;
    split(rt,x,y,val);
    split(x,x,z,val-1);
    merge(z,t[z].ch[0],t[z].ch[1]);
    merge(x,x,z);
    merge(rt,x,y);
}
int GetRank(int val){
    int x,y;
    x=y=0;
    split(rt,x,y,val-1);
    int ans=t[x].siz+1;
    merge(rt,x,y);
    return ans;
}
int GetVal(int k,int rnk){
    while(t[t[k].ch[0]].siz+1!=rnk){
        if(t[t[k].ch[0]].siz>=rnk){
            k=t[k].ch[0];
        }
        else {
            rnk-=(t[t[k].ch[0]].siz+1);
            k=t[k].ch[1];
        }
    }
    return t[k].val;
}
int pre(int val){
    int x,y;
    x=y=0;
    split(rt,x,y,val-1);
    int ans=GetVal(x,t[x].siz);
    merge(rt,x,y);
    return ans;
}
int nxt(int val){
    int x,y;
    x=y=0;
    split(rt,x,y,val);
    int ans=GetVal(y,1);
    merge(rt,x,y);
    return ans;
}
int main() {
    srand(23);
    std::cin>>n;
    t[0].prio=t[0].val=0x3f3f3f3f;t[0].siz=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&opt,&p);
        switch (opt){
            case 1:insert(p);break;
            case 2: del(p);break;
            case 3:printf("%d\n",GetRank(p));break;
            case 4:printf("%d\n",GetVal(rt,p));break;
            case 5:printf("%d\n",pre(p));break;
            case 6:printf("%d\n",nxt(p));break;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值