【数据结构】Treap——方便的平衡树
前言顾名思义,treap就是tree+Heap,复杂度与Splay的均摊
简介treap是一棵二叉查找树,与普通的二叉查找树不同,对于每个节点,它还记录一个随机值
以下为treap的基本操作,各种在这上面扩展出的其他的操作这里就不细讲了 Build我们可以发现一棵treap同时也是一棵迪笛卡尔树, //b[i].rd为位置i的随机值
//merge()为标记的合并,
void build(int q)
{
if(b[q].l)build(b[q].l);
if(b[q].r)build(b[q].r);
merge(q);
}
void build_treap()
{
int la,w;
n++;b[n].rd=2e9;
fo(i,1,n)
{
int la=0;
for(;za[0]&&b[za[za[0]]].rd<b[i].rd;za[0]--)
{
la=w=za[za[0]];
if(za[0]-1)b[w].fa=za[za[0]-1],b[za[za[0]-1]].r=w;
}
if(i>n)break;
b[i].l=la;
b[la].fa=i;
za[++za[0]]=i;
}
root=n;
build(root);
}
Splittreap当然离不开Split操作啦, //merge()为标记的合并,
typedef pair<int,int> TRP;
TRP split(int q,int si)
{
if(!si)return TRP(0,q);
TRP t;
if(si<=b[b[q].l].si)
{
t=split(b[q].l,si);
b[q].l=t.second;
t.second=q;
}else
{
t=split(b[q].r,si-1-b[b[q].l].si);
b[q].r=t.first;
t.first=q;
}
merge(q);
return t;
}
Merge合并就简单了,直接把较大的那个放到这个位置即可 //因为merge函数被标记合并占用了,所以只能用另一个词了
int amalgamate(int q,int w)
{
if(!q||!w)return q+w;
if(b[q].rd>b[w].rd)
{
b[q].r=amalgamate(b[q].r,w);
merge(q);
return q;
}
b[w].l=amalgamate(q,b[w].l);
merge(w);
return w;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |