FHQ Treap

\(split:\)将一棵\(Treap\)按照某种划分标准分成\(a\)\(b\)两棵\(Treap\)

\(x\)\(y\)分别表示\(a\)\(b\)的根

划分后,\(a\)中所有元素都\(\leqslant k\)\(b\)中所有元素都\(>k\)

权值分裂

\(code:\)

void split(int p,int k,int &x,int &y)
{
    if(!p)
    {
        x=y=0;
        return;
    }
    if(val[p]<=k) x=p,split(rs[p],k,rs[p],y);
    else y=p,split(ls[p],k,x,ls[p]);
    pushup(p);
}

排名分裂

\(code:\)

void split(int p,int k,int &x,int &y)
{
    if(!p)
    {
        x=y=0;
        return;
    }
    if(siz[ls[p]]<k) x=p,split(rs[p],k-siz[ls[p]]-1,rs[p],y);
    else y=p,split(ls[p],k,x,ls[p]);
    pushup(p);
}

\(merge:\)合并\(x\)\(y\),合并后的\(Treap\)的根为\(p\),因为先\(split\),所以\(x\)中所有元素都都小于\(y\)

\(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;
}
void merge(int &p,int x,int y)
{
    if(!x||!y)
    {   
        p=x+y;
        return;
    }
    if(key[x]<key[y]) p=x,merge(rs[p],rs[p],y);
    else p=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=p,split(rs[p],k,rs[p],y);
    else y=p,split(ls[p],k,x,ls[p]);
    pushup(p);
}
void insert(int v)
{
    split(root,v,x,y);
    merge(x,x,add(v));
    merge(root,x,y);
}
void del(int v)
{
    split(root,v,x,y);
    split(x,v-1,x,z);
    merge(z,ls[z],rs[z]);
    merge(x,x,z);
    merge(root,x,y);
}
int kth(int v)
{
    split(root,v-1,x,y);
    int ans=siz[x]+1;
    merge(root,x,y);
    return ans;
}
int get(int p,int k)
{
    if(k==siz[ls[p]]+1) return val[p];
    if(k<=siz[ls[p]]) return get(ls[p],k);
    else return get(rs[p],k-siz[ls[p]]-1);
}
int pre(int v)
{
    split(root,v-1,x,y);
    int ans=get(x,siz[x]);
    merge(root,x,y);
    return ans;
}
int nxt(int v)
{
    split(root,v,x,y);
    int ans=get(y,1);
    merge(root,x,y);
    return ans;
}
posted @ 2020-01-22 20:34  lhm_liu  阅读(191)  评论(0编辑  收藏  举报