平衡树

 

treap:
(1)树+堆。具体是随机某个节点的值,然后维护这个值满足堆的性质。
(2)代码实现

sbt:
(1)陈大神的节点大小平衡树,其实就是根据四种情况进行调整,而这四种情况也是其他bst会使用的调整方式。中心思想就是当节点信息变时,用maintain调整
(2)代码实现

procedure maintain(var t:longint);
begin
if s[left[left[t]]]>s[right[t]] then begin //左左>右的情况:先右旋,当前根右节点变了,需要调整,然后根变了,需要调整。
rightrotate(t);
maintain(right[t]);
maintain(t);
exit;
end;
if s[right[left[t]]]>s[right[t]] then begin //左右>右的情况:先左旋左儿子,使左右变成左儿子,再左旋,让左儿子变成根,至此,当前根的左儿子要调整,当前根的右儿子也要调整,当前根也要调整
leftrotate(left[t]);
rightrotate(t);
maintain(left[t]);
maintain(right[t]);
maintain(t);
exit;
end;
if s[right[right[t]]]>s[left[t]] then begin
leftrotate(t);
maintain(left[t]);
maintain(t);
exit;
end;
if s[left[right[t]]]>s[left[t]] then begin
rightrotate(right[t]);
leftrotate(t);
maintain(left[t]);
maintain(right[t]);
maintain(t);
end;
end;
View Code

splay:

(1)通过不断翻转来实现平衡

(2)代码实现

 

平衡树有一些公共的操作

find:查找是否有只为v的节点

function find(var t,v:longint):boolean;inline;
begin
   if t=0 then
      exit(false);
   if v<key[t] then
      find:=find(left[t],v)
   else
      find:=(key[t]=v)or find(right[t],v);
end;
View Code

rank:查找值为v的点的排名

具体做法:

1)如果当前是空节点,那就退出1

2)不是的话,如果v小于等于当前节点的值,那么就往左儿子找,如果大于当前节点,说明v值得排名至少有s[left[t]]+1,再查找右儿子。

function rank(var t,v:longint):longint;inline;
begin
   if t=0 then
      exit(1);
   if v<=key[t] then
      rank:=rank(left[t],v)
   else
      rank:=s[left[t]]+1+rank(right[t],v);
end;
View Code

select:查找排名为k的点的值

具体做法:

1)如果当前这个点的左儿子+1=排名k,那么就是这个点啦

2)如果不是的话,如果k小于等于左儿子的节点数,那么就找左儿子,如果不是,那么找右儿子中排名为k-1-s[left[t]]的点

pred:查找值小于(不能等于)v的最大值

function pred(var t,v:longint):longint;inline;
begin
   if t=0 then
      exit(v);
   if v<=key[t] then
      pred:=pred(left[t],v)
   else begin
      pred:=pred(right[t],v);
      if pred=v then
         pred:=key[t];
   end;
end;
View Code

(把exit(v)变成exit(maxlongint)也可以?总觉得我以前就是用maxlongint)

succ:查找值大于(不能等于)v的最小值

function succ(var t,v:longint):longint;inline;
begin
   if t=0 then
      exit(v);
   if key[t]<=v then
      succ:=succ(right[t],v)
   else begin
      succ:=succ(left[t],v);
      if succ=v then
         succ:=key[t];
   end;
end;
View Code

 

 

 

bzoj1588 [HNOI2002]营业额统计 (treap)

bzoj1251: 序列终结者 (splay)

bzoj1208: [HNOI2004]宠物收养所 (sbt)

http://www.lydsy.com/JudgeOnline/problem.php?id=3224

http://www.lydsy.com/JudgeOnline/problem.php?id=3223

http://www.lydsy.com/JudgeOnline/problem.php?id=3196

原文地址:https://www.cnblogs.com/Macaulish/p/4290931.html