• 平衡树


     

    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

  • 相关阅读:
    如何查看python的当前版本号
    Android数据库程序开发必备工具SqliteDev 狼人:
    Android四种Activity的加载模式 狼人:
    20+ 个很棒的 jQuery 文件上传插件或教程(此文值得“推荐”和“收藏”) 狼人:
    艾伟:10分钟去除天天团购系统版权 狼人:
    WIN7,server2008 IIS 伪静态 不能显示特殊图片 加号 减号 “+”,""号的图片需要转义才可以显示 狼人:
    近百余款最新HTML5应用案例给大伙儿共享了 狼人:
    shopex李钟伟:独立电子商务发展与网络购物 狼人:
    《天将客户关系管理系统》 狼人:
    Shopex V4.8.4 V4.8.5 后台拿Shell 0Days 狼人:
  • 原文地址:https://www.cnblogs.com/Macaulish/p/4290931.html
Copyright © 2020-2023  润新知