• 数据结构:可持久化平衡树


    首先吐槽一下,我刚开始找了一篇看起来很不错的模板代码,然后学习了一遍,然后直接WA

    我发现博主的维护rnd的那里出毛病了,我改了之后最后一个点WA

    然后发现,它没有copy结点,也就是没有可持久化,只是一颗无旋Treap而已。。

    不说了,感谢引导我走向正确的作者:http://www.cnblogs.com/nbwzyzngyl/p/7977369.html

    这是一种非常好写的treap 核心操作有两个,一个是split一个是merge。
    
    split(node,k,x,y) 意思是把以node为跟的子树分成两部分,一部分小于等于k(根为x),一部分大于k(根为y)。在可持久化的时候要保证以前的树的形态不变,就要每一次copy一个节点过来。
    
    而我们每一次递归只会访问一个节点的左右子树中的一个节点,又因为treap的均摊深度为log,所以总体的空间为nlogn,是非常高效的。
    
    说完split接下来是merge
    
    merge函数,是有返回值的,merge(x,y) 是把以x为根的子树和以y为根的子树合并起来,返回这棵新的树的根,递归的实现,非常好懂。

    以上是对无旋Treap的介绍,直接在这个的基础上完成可持久化操作就可以了

    然后是一份清晰的模板:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 int cnt;
      4 int rt[500005];
      5 struct Node
      6 {
      7     int l,r,size,rnd,v;
      8 }t[500005*50];
      9 void update(int k)
     10 {
     11     t[k].size=t[t[k].l].size+t[t[k].r].size+1;
     12 }
     13 void newnode(int &k,int x)
     14 {
     15     k=++cnt;
     16     t[k].v=x;t[k].size=1;t[k].rnd=rand();
     17 }
     18 int merge(int a,int b)
     19 {
     20     if(a==0||b==0)return a+b;
     21     if(t[a].rnd>t[b].rnd)
     22     {
     23         int p=++cnt;t[p]=t[a];
     24         t[p].r=merge(t[p].r,b);
     25         update(p);return p;
     26     }
     27     else
     28     {
     29         int p=++cnt;t[p]=t[b];
     30         t[p].l=merge(a,t[p].l);
     31         update(p);return p;
     32     }
     33 }
     34 void split(int now,int k,int &x,int &y)
     35 {
     36     if(now==0) x=y=0;
     37     else
     38     {
     39         if(t[now].v<=k)
     40         {
     41             x=++cnt;t[x]=t[now];
     42             split(t[x].r,k,t[x].r,y);
     43             update(x);
     44         }
     45         else 
     46         {
     47             y=++cnt;t[y]=t[now];
     48             split(t[y].l,k,x,t[y].l);
     49             update(y);
     50         }
     51     }
     52 }
     53 void Delete(int &root,int w)
     54 {
     55     int x=0,y=0,z=0;
     56     split(root,w,x,z);
     57     split(x,w-1,x,y);
     58     y=merge(t[y].l,t[y].r);
     59     root=merge(merge(x,y),z);
     60 }
     61 void Insert(int &root,int w)
     62 {
     63     int x=0,y=0,z=0;
     64     split(root,w,x,y);
     65     newnode(z,w);
     66     root=merge(merge(x,z),y);
     67 }
     68 int getval(int k,int w)
     69 {
     70     if(w==t[t[k].l].size+1)return t[k].v;
     71     else if(w<=t[t[k].l].size)return getval(t[k].l,w);
     72     else return getval(t[k].r,w-t[t[k].l].size-1);
     73 }
     74 int getkth(int &root,int w)
     75 {
     76     int x,y;
     77     split(root,w-1,x,y);
     78     int ans=t[x].size+1;
     79     root=merge(x,y);
     80     return ans;
     81 }
     82 int getpre(int &root,int w)
     83 {
     84     int x,y,k,ans;
     85     split(root,w-1,x,y);
     86     if(!x)return -2147483647;
     87     k=t[x].size;
     88     ans=getval(x,k);
     89     root=merge(x,y);
     90     return ans;
     91 }
     92 int getnex(int &root,int w)
     93 {
     94     int x,y,ans;
     95     split(root,w,x,y);
     96     if(!y)return 2147483647;
     97     else ans=getval(y,1);
     98     root=merge(x,y);
     99     return ans;
    100 }
    101 int main()
    102 {
    103     int n,f,w,tim;
    104     scanf("%d",&n);
    105     for(int i=1;i<=n;++i)
    106     {
    107         scanf("%d%d%d",&tim,&f,&w);
    108         rt[i]=rt[tim];
    109         if(f==1) Insert(rt[i],w);
    110         else if(f==2) Delete(rt[i],w);
    111         else if(f==3) printf("%d
    ",getkth(rt[i],w));
    112         else if(f==4) printf("%d
    ",getval(rt[i],w));
    113         else if(f==5) printf("%d
    ",getpre(rt[i],w));
    114         else printf("%d
    ",getnex(rt[i],w));
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    爬虫中动态的POST参数
    Sublime3注册码和安装中文包
    [pytorch][进阶之路]pytorch学习笔记二-自动求导和module
    [pytorch][进阶之路]pytorch学习笔记一
    [python][进阶之路]理解python中的深复制和浅复制
    [python][matlab]在python36上安装matlab2015b引擎
    [python][进阶之路]list复制引发的问题
    [python][pandas]DataFrame的基本操作
    [Algorithm]ADMM简明理解
    [python][cpp]对浮点数进行n位翻转
  • 原文地址:https://www.cnblogs.com/aininot260/p/9519563.html
Copyright © 2020-2023  润新知