首页 > 其他 > 详细

可持久化平衡树

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

因为\(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);//后继

可持久化平衡树

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!