您的位置:首页 > 其它

treap平衡树

2017-07-31 21:13 92 查看
题表:普通平衡树

           宠物收养所

           营业额统计

           文艺平衡树

treap满足二叉树的性质,当前节点的val>左儿子的val,<右儿子的val

为了保持平衡,每个节点有rnd值,满足堆的性质

数组实现#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define N 100005
using namespace std;
struct treap
{
int l,r,v,size,rnd,w;
}t
;
int n,size,root,ans;
void update(int k)
{
t[k].size=t[t[k].l].size+t[t[k].r].size+t[k].w;
}
void rturn(int &k)
{
int x=t[k].l;
t[k].l=t[x].r;t[x].r=k;
t[x].size=t[k].size;update(k);k=x;
return ;
}
void lturn(int &k)
{
int x=t[k].r;
t[k].r=t[x].l;t[x].l=k;
t[x].size=t[k].size;update(k);k=x;
return ;
}
void insert(int &k,int x)
{
if(k==0)
{
size++;k=size;
t[k].size=t[k].w=1;t[k].rnd=rand();t[k].v=x;
return ;
}
t[k].size++;
if(t[k].v==x) t[k].w++;
else
if(t[k].v>x)
{
insert(t[k].l,x);
if(t[t[k].l].rnd<t[k].rnd) rturn(k);
}
else
{
insert(t[k].r,x);
if(t[t[k].r].rnd<t[k].rnd) lturn(k);
}
}
void del(int &k,int x)
{
if(k==0) return ;
if(t[k].v==x)
{
if(t[k].w>1)
{
t[k].size--;t[k].w--;return ;
}
if(t[k].l*t[k].r==0) k=t[k].l+t[k].r;
else
if(t[t[k].l].rnd<t[t[k].r].rnd) {rturn(k);del(k,x);}
else {lturn(k);del(k,x);}
}
else
if(t[k].v>x) {t[k].size--; del(t[k].l,x); }
else {t[k].size--; del(t[k].r,x); }
}
int rank(int k,int x)//查找x的排名
{
if(k==0) return 0;
if(t[k].v==x) return t[t[k].l].size+1;
else
if(x>t[k].v) return t[t[k].l].size+t[k].w+rank(t[k].r,x);
else return rank(t[k].l,x);
}
int rank2(int k,int x)//查找排名为x的数
{
if(k==0) return 0;
if(x<=t[t[k].l].size)
{

return rank2(t[k].l,x);
}
else
if(x>t[t[k].l].size+t[k].w)
return rank2(t[k].r,x-t[t[k].l].size-t[k].w);
else return t[k].v;
}
void pre(int k,int x)//查找x的前驱
{
if(k==0) return ;
if(t[k].v<x)
{
ans=k;pre(t[k].r,x);
}
else
pre(t[k].l,x);
}
void sub(int k,int x)//查找
x的后继
{

if(k==0) return ;
if(t[k].v>x)
{
ans=k;sub(t[k].l,x);
}
else sub(t[k].r,x);
}
int main()
{
freopen("phs.in","r",stdin);
freopen("phs.out","w",stdout);
scanf("%d",&n);
int opt,x;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&opt,&x);
if(opt==1) insert(root,x);
if(opt==2) del(root,x);
if(opt==3) printf("%d\n",rank(root,x));
if(opt==4) printf("%d\n",rank2(root,x));
if(opt==5) { ans=0; pre(root,x); printf("%d\n",t[ans].v);}
if(opt==6) { ans=0; sub(root,x); printf("%d\n",t[ans].v);}
}
//while(1);
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  treap