可持久化平衡树

Posted lhm-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可持久化平衡树相关的知识,希望对你有一定的参考价值。

因为(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
",siz[x]+1);
merge(root[i],x,y);//查询x的排名
        
printf("%d
",query(root[i],a));//查询排名为x的数

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

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

以上是关于可持久化平衡树的主要内容,如果未能解决你的问题,请参考以下文章

可持久化平衡树

[luogu3835]可持久化平衡树

可持久化平衡树

P3919 模板可持久化数组(可持久化线段树/平衡树)

平衡树与可持久化treap

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)