Treap

Treap

Treap(树堆)是一种 弱平衡 的 二叉搜索树。它同时符合二叉搜索树和堆的性质,名字也因此为 tree(树)和 heap(堆)的组合。 -oiwiki

二叉搜索树的特点是:左节点比父点大,右节点比父小。

堆的特点是

朴素二叉搜索树的问题。在给朴素搜索树插入一个新节点时,我们需要从这个搜索树的根节点开始递归,如果新节点比当前节点小,那就向左递归,反之亦然。

在给定的特定的数据下,二叉树会退化成一条链。

更新节点

void push(int x){sz[x] = sz[ls[x]] + sz[rs[x]] + 1 ;}//更新

裂开

void spl(int p,int v,int &x,int &y){
    if(!p)return x=y=0,void();
    if(val[p]<=v)spl(rs[p],v,rs[x=p],y);
    else spl(ls[p],v,x,ls[y=p]);
    push(p);
}

合并

int mer(int x, int y){
    if(!x||!y)return x|y;
    if(rd[x] < rd[y])return ls[y] = mer(x,ls[y]),push(y),y;
    return rs[x] = mer(rs[x],y),push(x),x;
}

新建

int nd(int v){//新建
    int x = ++ node;
    val[x] = v,rd[x] = rand();sz[x] = 1;
    return x;
}

插入

void ins(int v)//插入
    int x = 0,y = 0;
    spl(R,v-1,x,y),R = mer(mer(x,nd(v)),y);
}

删除

void del(int v){//删除
    int x = 0, y = 0, z= 0;
    spl(R,v,x,z),spl(x,v-1,x,y);
    R = mer(mer(x,y = mer(ls[y],rs[y])),z);
}

求前序

int pre(int v){
    int p = R,ans = 0;
    while(1){
    if(!p)return ans;
    else if(v <= val[p])p = ls[p];
    else ans = val[p],p=rs[p];
    }
}

求后序

int suc(int v){
    int p = R,ans = 0;
    while(1){
        if(!p)return ans;
        else if(v>=val[p])p=rs[p];
        else ans = val[p],p=ls[p];
    }

}

根据排名求值

int kth(int k){
	int p=R;
	while(1){
		if(k<=sz[ls[p]])p=ls[p];
		else if(k==sz[ls[p]]+1)return val[p];
		else k-=sz[ls[p]]+1,p=rs[p];
	}
}

根据值求排名

int rnk(int v){
    int x=0,y=0,ans=0;
    spl(R,v-1,x,y),ans=sz[x]+1;
    return R=mer(x,y),ans;


}

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9 + 7;

int R,node,ls[N],rs[N],val[N],rd[N],sz[N],n;

void push(int x){sz[x] = sz[ls[x]] + sz[rs[x]] + 1 ;}//更新

void spl(int p,int v,int &x,int &y){//裂开
    if(!p)return x=y=0,void();
    if(val[p]<=v)spl(rs[p],v,rs[x=p],y);
    else spl(ls[p],v,x,ls[y=p]);
    push(p);
}

int mer(int x, int y){//合并
    if(!x||!y)return x|y;
    if(rd[x] < rd[y])return ls[y] = mer(x,ls[y]),push(y),y;
    return rs[x] = mer(rs[x],y),push(x),x;
}

int nd(int v){//新建
    int x = ++ node;
    val[x] = v,rd[x] = rand();sz[x] = 1;
    return x;
}
void ins(int v)//插入
    int x = 0,y = 0;
    spl(R,v-1,x,y),R = mer(mer(x,nd(v)),y);
}

void del(int v){//删除
    int x = 0, y = 0, z= 0;
    spl(R,v,x,z),spl(x,v-1,x,y);
    R = mer(mer(x,y = mer(ls[y],rs[y])),z);
}

int pre(int v){
    int p = R,ans = 0;
    while(1){
    if(!p)return ans;
    else if(v <= val[p])p = ls[p];
    else ans = val[p],p=rs[p];
    }
}

int suc(int v){
    int p = R,ans = 0;
    while(1){
        if(!p)return ans;
        else if(v>=val[p])p=rs[p];
        else ans = val[p],p=ls[p];
    }

}
int kth(int k){
	int p=R;
	while(1){
		if(k<=sz[ls[p]])p=ls[p];
		else if(k==sz[ls[p]]+1)return val[p];
		else k-=sz[ls[p]]+1,p=rs[p];
	}
}

int rnk(int v){
    int x=0,y=0,ans=0;
    spl(R,v-1,x,y),ans=sz[x]+1;
    return R=mer(x,y),ans;


}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		int op,x; cin>>op>>x;
		if(op==1)ins(x);
		if(op==2)del(x);
		if(op==3)cout<<rnk(x)<<endl;
		if(op==4)cout<<kth(x)<<endl;
		if(op==5)cout<<pre(x)<<endl;
		if(op==6)cout<<suc(x)<<endl;
	}
	return 0;

}
posted @   Erfu  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示