zoukankan      html  css  js  c++  java
  • 【HDU1512/ZOJ2334】Monkey King-左偏树-可合并堆

    Problem Monkey King

    Solution

    本题是裸的左偏树,一个模板就可以过了。对于每个操作对节点先删除/2再合并。
    注意本题在HDU上评测特别坑,是多组数据,而且经常出现MLE的情况。很可能是其中初始化的问题。
    斜堆可以更快。具体请查询IOI2015黄源河集训队论文

    AC Code

    #include "iostream"
    #include "cstdio"
    using namespace std;
    struct LeftistTree{
        int dist,n,lc,rc,fa;
    }a[100010];
    int find(int x){
        while(a[x].fa!=x)x=a[x].fa;
        return x;
    }
    int n,m;
    int x,y,ans,fx,fy,u,v,dx,dy;
    int merge(int x,int y){
        if(x==0)return y;
        if(y==0)return x;
        if(a[x].n<a[y].n)swap(x,y);
        a[x].rc=merge(a[x].rc,y);
        a[a[x].rc].fa=x;
        if(a[a[x].lc].dist<a[a[x].rc].dist)swap(a[x].lc,a[x].rc);
        if(a[x].rc!=0)a[x].dist=a[a[x].rc].dist+1;
        else a[x].dist=0;
        return x;
    }
    int delt(int x){
        int ret=merge(a[x].lc,a[x].rc);
        a[a[x].lc].fa=ret;
        a[a[x].rc].fa=ret;
        a[x].lc=a[x].rc=a[x].dist=0;
        a[x].fa=x;
        return ret;
    }
    int main(){
        while(~scanf("%d",&n)){
            a[0].lc=0;a[0].rc=0;a[0].fa=0;
            for(int i=1;i<=n;i++)scanf("%d",&a[i].n),a[i].fa=i,a[i].dist=0,a[i].lc=0,a[i].rc=0;
            scanf("%d",&m);
            for(int i=1;i<=m;i++){
                scanf("%d%d",&x,&y);    
                fx=find(x),fy=find(y);
                if(fx==fy)printf("-1
    ");else{
                    dx=delt(fx),dy=delt(fy);
                    a[fx].n/=2;
                    a[fy].n/=2;
                    dx=merge(dx,fx);
                    dy=merge(dy,fy);
                    ans=merge(dx,dy);
                    printf("%d
    ",a[ans].n);
                }
            }
        }
    }
  • 相关阅读:
    Python——6切片
    Python——5函数
    Python——4Dict和Set类型
    C# for循环
    C# while循环
    C#循环结构
    C#判断
    C#运算符
    windows安装IIS不成功的原因
    “未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序
  • 原文地址:https://www.cnblogs.com/skylynf/p/7140477.html
Copyright © 2011-2022 走看看