模板Treap
Posted wzj-xhjbk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板Treap相关的知识,希望对你有一定的参考价值。
Treap,又称树堆,是一种通过堆性质来维持BST平衡的数据结构。具体体现在对于树上每一个点来说,既有BST维护的值,又有一个堆维护的随机生成的值。维护平衡性的办法是根据堆维护的值的相对大小关系进行左旋和右旋这两种操作,在旋转的前后,依然满足BST性质。
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int ans;
struct node{int lc,rc,val,cnt,size,rd;};
struct Treap{
#define ls t[x].lc
#define rs t[x].rc
node t[maxn];
int root,tot;
Treap():root(0),tot(0){}
~Treap(){}
inline int newnode(int val){
++tot,t[tot].size=t[tot].cnt=1,t[tot].val=val,t[tot].rd=rand();
return tot;
}
inline void pushup(int x){
t[x].size=t[ls].size+t[rs].size+t[x].cnt;
}
inline void zig(int &x){
int lson=ls;
ls=t[lson].rc,t[lson].rc=x,x=lson;
pushup(t[lson].rc),pushup(x);
}
inline void zag(int &x){
int rson=rs;
rs=t[rson].lc,t[rson].lc=x,x=rson;
pushup(t[rson].lc),pushup(x);
}
void insert(int &x,int val){
if(!x)x=newnode(val);
else if(val==t[x].val)++t[x].cnt,++t[x].size;
else if(val<t[x].val){
++t[x].size,insert(ls,val);
if(t[ls].rd<t[x].rd)zig(x);
}else{
++t[x].size,insert(rs,val);
if(t[rs].rd<t[x].rd)zag(x);
}
}
void del(int &x,int val){
if(!x)return;
else if(val==t[x].val){
if(t[x].cnt>1)--t[x].cnt,--t[x].size;
else if(!ls||!rs)x=ls+rs;
else if(t[ls].rd<t[rs].rd)zig(x),del(x,val);
else zag(x),del(x,val);
}
else if(val<t[x].val)--t[x].size,del(ls,val);
else --t[x].size,del(rs,val);
}
int getrank(int x,int val){
if(val<t[x].val)return getrank(ls,val);
else if(val>t[x].val)return getrank(rs,val)+t[ls].size+t[x].cnt;
else return t[ls].size+1;
}
int kth(int x,int k){
if(k<=t[ls].size)return kth(ls,k);
else if(k>t[ls].size+t[x].cnt)return kth(rs,k-t[ls].size-t[x].cnt);
else return t[x].val;
}
void pre(int x,int val){
if(!x)return;
else if(t[x].val<val)ans=t[x].val,pre(rs,val);
else pre(ls,val);
}
void nxt(int x,int val){
if(!x)return;
else if(t[x].val>val)ans=t[x].val,nxt(ls,val);
else nxt(rs,val);
}
}treap;
int main(){
int n;scanf("%d",&n);
while(n--){
int opt,val;scanf("%d%d",&opt,&val);
switch(opt){
case 1:treap.insert(treap.root,val);break;
case 2:treap.del(treap.root,val);break;
case 3:printf("%d
",treap.getrank(treap.root,val));break;
case 4:printf("%d
",treap.kth(treap.root,val));break;
case 5:treap.pre(treap.root,val);printf("%d
",ans);break;
case 6:treap.nxt(treap.root,val);printf("%d
",ans);break;
}
}
return 0;
}
以上是关于模板Treap的主要内容,如果未能解决你的问题,请参考以下文章