累加器传送门:
http://blog.csdn.net/NOIAu/article/details/71775000
以前经常听着lmy大佬说平衡树怎么怎么样,问到一道题怎么做的时候(手写个平衡树就好了啊),觉得好厉害,终于自己学了最简单的平衡树——Treap
首先,Treap,顾名思义就是Tree和heap的结合,也就是具有堆性质的二叉搜索树,好了,想必讲到这里,大家已经完全明白了Treap的原理和实现方法,下面贴上代码
#include<cstdio>
#include<iostream>
#include<cstring>
#define MAXN 100000+10
using namespace std;
int n,sz,root,ans;
inline const int read(){
register int x=0,f=1;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return f*x;
}
inline int rand_num(){
static int seed=520;
return seed=int(seed*48271LL%2147483647);
}
struct Treap{
int lson,rson,val,rnd,size,wei;
}treap[MAXN];
void update(int k){
treap[k].size=treap[treap[k].lson].size+treap[treap[k].rson].size+treap[k].wei;
}
void Right_Ratote(int &k){
int t=treap[k].lson;treap[k].lson=treap[t].rson;treap[t].rson=k;
treap[t].size=treap[k].size;update(k);k=t;
}
void Left_Ratote(int &k){
int t=treap[k].rson;treap[k].rson=treap[t].lson;treap[t].lson=k;
treap[t].size=treap[k].size;update(k);k=t;
}
void insert(int &k,int x){
if(k==0){
k=++sz;treap[k].size=treap[k].wei=1;
treap[k].val=x;treap[k].rnd=rand_num();return;
}
treap[k].size++;
if(treap[k].val==x) treap[k].wei++;
else if(treap[k].val<x){
insert(treap[k].rson,x);
if(treap[treap[k].rson].rnd<treap[k].rnd)
Left_Ratote(k);
}else{
insert(treap[k].lson,x);
if(treap[treap[k].lson].rnd<treap[k].rnd)
Right_Ratote(k);
}
}
void del(int &k,int x){
if(k==0) return;
if(treap[k].val==x){
if(treap[k].wei>1){
treap[k].wei--;
treap[k].size--;
return;
}
if(treap[k].lson*treap[k].rson==0){
k=treap[k].lson+treap[k].rson;
}else if(treap[treap[k].lson].rnd<treap[treap[k].rson].rnd){
Right_Ratote(k);
del(k,x);
}else{
Left_Ratote(k);
del(k,x);
}
}else if(treap[k].val<x){
treap[k].size--;
del(treap[k].rson,x);
}else{
treap[k].size--;
del(treap[k].lson,x);
}
}
int query_rank(int k,int x){
if(!k) return 0;
if(treap[k].val==x) return treap[treap[k].lson].size+1;
else if(treap[k].val<x) return treap[treap[k].lson].size+treap[k].wei+query_rank(treap[k].rson,x);
else return query_rank(treap[k].lson,x);
}
int query_num(int k,int x){
if(!k) return 0;
if(x<=treap[treap[k].lson].size) return query_num(treap[k].lson,x);
else if(x>treap[treap[k].lson].size+treap[k].wei) return query_num(treap[k].rson,x-treap[treap[k].lson].size-treap[k].wei);
else return treap[k].val;
}
void query_LB(int k,int x){
if(!k) return;
if(treap[k].val<x){
ans=k;
query_LB(treap[k].rson,x);
}else{
query_LB(treap[k].lson,x);
}
}
void query_UB(int k,int x){
if(!k) return;
if(treap[k].val>x){
ans=k;
query_UB(treap[k].lson,x);
}else{
query_UB(treap[k].rson,x);
}
}
int main(){
int opt,x;
n=read();
for(register int i=1;i<=n;i++){
opt=read(),x=read();
switch(opt){
case 1:insert(root,x);break;
case 2:del(root,x);break;
case 3:printf("%d\n",query_rank(root,x));break;
case 4:printf("%d\n",query_num(root,x));break;
case 5:ans=0,query_LB(root,x);printf("%d\n",treap[ans].val);break;
case 6:ans=0,query_UB(root,x);printf("%d\n",treap[ans].val);break;
}
}
return 0;
}
本文详细介绍了Treap树的概念,它是结合了二叉搜索树和堆性质的数据结构。通过示例代码展示了Treap树的基本操作,包括插入、删除、查询等,并提供了详细的解释和参考资料。

2093

被折叠的 条评论
为什么被折叠?



