luogu_P3377 左偏树(可并堆)

Posted coclhy

tags:

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

传送门:https://www.luogu.org/problem/P3377

左偏树:左偏!也就是下面这种左边大,右边小的树

技术图片

可并堆:可以合并的堆(堆:维护最值的数据结构)

技术图片

核心(细节): 

  先来代码

int merge(int x,int y){
    if(!x||!y) return x+y;
    if(val[x]>val[y] || (val[x]==val[y]&&x>y)) swap(x,y);
    rs[x]=merge(rs[x],y);
    rt[rs[x]]=rt[ls[x]]=x;
    if(h[rs[x]]>h[ls[x]]) swap(rs[x],ls[x]);
    h[x]=h[rs[x]]+1;
    return x;
}

在合并时,往右子树走,当发现右边的值不合法时,则另另一个堆的值来swap

  以最大值为例: 当发现x<y时,让堆的右儿子为y,把原来那颗子树扯出来,继续合并

  每次合并完之后更新高度(一个节点的高度=它的右儿子高度+1)

  技术图片

还有一点就是在删除的时候,先找到堆顶,删除,然后merge(rs[x],ls[x])

记得令 root[x]=merge(rs[x],ls[x]) 因为有路径压缩,所以有很多节点的top还是x

技术图片
#include<cstdio>
#include<algorithm>
#define R register
using namespace std;
int n,m,val[100100],rt[100100],ls[100100],rs[100100],h[100100];
int find(int x){
    return rt[x]==x? x:rt[x]=find(rt[x]);
}
int merge(int x,int y){
    if(!x||!y) return x+y;
    if(val[x]>val[y] || (val[x]==val[y]&&x>y)) swap(x,y);
    rs[x]=merge(rs[x],y);
    rt[rs[x]]=rt[ls[x]]=x;
    if(h[rs[x]]>h[ls[x]]) swap(rs[x],ls[x]);
    h[x]=h[rs[x]]+1;
    return x;
}
void pop(int x){
    val[x]=-1;rt[rs[x]]=rs[x];rt[ls[x]]=ls[x];
    rt[x]=rt[rs[x]]=rt[ls[x]]=merge(rs[x],ls[x]);
    return;
}
int main (){
    scanf("%d%d",&n,&m);
    for(R int i=1;i<=n;i++){
        scanf("%d",&val[i]);rt[i]=i;
    }
    h[0]=-1;
    for(R int c,x,y,i=1;i<=m;i++){
        scanf("%d",&c);
        if(c==1){
            scanf("%d%d",&x,&y);
            if(val[x]==-1|| val[y]==-1) continue;
            x=find(x);y=find(y);
            if(x==y) continue;
            rt[x]=rt[y]=merge(x,y);        
        }
        else{
            scanf("%d",&x);
            if(val[x]==-1) printf("-1
");
            else {
                y=find(x);
                printf("%d
",val[y]);
                pop(y);
            }
        }
    }
    return 0;
}
View Code

 

以上是关于luogu_P3377 左偏树(可并堆)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 [P3377] 左偏树(可并堆)

[luogu3377]模板左偏树(可并堆)

P3377 模板左偏树(可并堆)

luogu P3377 左偏树(可并堆) 模板

洛谷 P3377 模板左偏树(可并堆)

Luogu P3377模板左偏树(可并堆)