码迷,mamicode.com
首页 > 其他好文 > 详细

可持久化平衡树

时间:2020-01-22 21:48:01      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:直接   ret   mat   push   cpp   treap   key   lin   rand   

因为\(Treap\)只认儿子不认爸爸,所以方便复制,直接可持久化就行了

\(code:\)

int add(int x)
{
    val[++tot]=x;
    siz[tot]=1;
    key[tot]=rand();
    return tot;
}
void pushup(int x)
{
    siz[x]=siz[ls[x]]+siz[rs[x]]+1;
}
int cpy(int x)
{
    tot++;
    val[tot]=val[x];
    siz[tot]=siz[x];
    key[tot]=key[x];
    ls[tot]=ls[x];
    rs[tot]=rs[x];
    return tot;
}
void merge(int &p,int x,int y)
{
    if(!x||!y)
    {   
        p=x+y;
        return;
    }
    if(key[x]<key[y]) p=cpy(x),merge(rs[p],rs[p],y);
    else p=cpy(y),merge(ls[p],x,ls[p]);
    pushup(p);
}
void split(int p,int k,int &x,int &y)
{
    if(!p)
    {
        x=y=0;
        return;
    }
    if(val[p]<=k)
    {
        x=cpy(p);
        split(rs[x],k,rs[x],y);
        pushup(x);
    }
    else
    {
        y=cpy(p);
        split(ls[y],k,x,ls[y]);
        pushup(y);
    }
}
int query(int p,int k)
{
    if(k==siz[ls[p]]+1) return val[p];
    if(k<=siz[ls[p]]) return query(ls[p],k);
    else return query(rs[p],k-siz[ls[p]]-1);
}

split(root[i],a,x,y);
merge(x,x,add(a));
merge(root[i],x,y);//插入

split(root[i],a,x,y);
split(x,a-1,x,z);
merge(z,ls[z],rs[z]);
merge(x,x,z);
merge(root[i],x,y);//删除
        
split(root[i],a-1,x,y);
printf("%d\n",siz[x]+1);
merge(root[i],x,y);//查询x的排名
        
printf("%d\n",query(root[i],a));//查询排名为x的数

split(root[i],a-1,x,y);
if(!siz[x]) puts("-2147483647");
printf("%d\n",query(x,siz[x]));
merge(root[i],x,y);//前驱

split(root[i],a,x,y);
if(!siz[y]) puts("2147483647");
else printf("%d\n",query(y,1));
merge(root[i],x,y);//后继

可持久化平衡树

标签:直接   ret   mat   push   cpp   treap   key   lin   rand   

原文地址:https://www.cnblogs.com/lhm-/p/12229559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!