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;
}
“风雪越是呼啸,雪莲越是绽放”
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!