zoukankan      html  css  js  c++  java
  • [模板] 左偏树

    左偏树,可以在O(logn1+logn2)的时间内完成两个堆的合并,核心操作是merge(x,y)

    pop操作可以通过merge根节点的两个子节点实现

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    const int MAXN = 100005;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    int val[MAXN],dis[MAXN],ch[MAXN][2],fa[MAXN];
    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);
        ch[x][1]=merge(ch[x][1],y);
        fa[ch[x][1]]=x;
        if(dis[ch[x][0]]<dis[ch[x][1]])swap(ch[x][0],ch[x][1]);
        dis[x]=dis[ch[x][1]]+1;
        return x;
    }
    inline int fnd(int x){while(fa[x])x=fa[x];return x;}
    inline int pop(int x){
        val[x]=-1;
        fa[ch[x][0]]=fa[ch[x][1]]=0;
        merge(ch[x][0],ch[x][1]);
    }
    
    int n,m;
    
    int main(){
        n=rd();m=rd();
        dis[0]=-1;
        for(int i=1;i<=n;i++){
            val[i]=rd();
        }
        int q,x,y;
        for(int i=1;i<=m;i++){
            q=rd();x=rd();
            if(q==1){
                y=rd();
                if(val[x]==-1||val[y]==-1)continue;
                if(x==y)continue;
                x=fnd(x);y=fnd(y);
                merge(x,y);
            }else{
                if(val[x]==-1){puts("-1");continue;} 
                x=fnd(x);
                printf("%d
    ",val[x]);
                pop(x);
            }
        }
        return 0;
    }
    未经许可,禁止搬运。
  • 相关阅读:
    Linux PXE无人值守网络装机
    Linux 自动化部署DNS服务器
    Linux DNS服务配置
    Mysql数据库基础学习笔记
    Linux AIDE(文件完整性检测)
    mysql:[Err] 1068
    sql的date、时间函数、时间戳
    hive之建立分区表和分区
    excel转sql代码
    spark-submit之使用pyspark
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9638239.html
Copyright © 2011-2022 走看看