zoukankan      html  css  js  c++  java
  • zoj2334 Monkey King , 并查集,可并堆,左偏树

    提交地址:点击打开链接

    题意:  N(N<=10^5)仅仅猴子,初始每仅仅猴子为自己猴群的猴王。每仅仅猴子有一个初始的力量值。这些猴子会有M次会面。

    每次两仅仅猴子x,y会面,若x,y属于同一个猴群输出-1,否则将x,y所在猴群的猴王的力量值减半,然后合并这两个猴群。

    新猴群中力量值最高的为猴王。

    输出新猴王的力量值。


    分析:涉及集合的查询,合并,取最值。 利用并查集和左偏树就可以解决。


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 200000;
    int tot, v[maxn], l[maxn], r[maxn], d[maxn], f[maxn];
    int findset(int x)
    {return f[x]==x?x:f[x]=findset(f[x]);}
    int Merge(int x, int y)
    {
        if(!x) return y;
        if(!y) return x;
        if(v[x] < v[y]) swap(x, y);  //大顶堆
        r[x] = Merge(r[x], y); //递归合并右子树和Y
        f[r[x]] = x;  //更新T右子树的根
        if(d[l[x]] < d[r[x]]) //维护堆性质
            swap(l[x], r[x]);
        d[x] = d[ r[x] ] + 1;
        return x;
    }
    int Init(int x)
    {
        tot++;
        v[tot] = x;
        f[tot] = tot;
        l[tot] = r[tot] = d[tot] = 0;
    }
    int Insert(int x, int y)
    {
        return Merge(x, Init(y));
    }
    int Top(int x)
    {
        return v[x];
    }
    int Pop(int x)
    {
        int L = l[x], R = r[x];
        f[L] = L;
        f[R] = R;
        v[x] /= 2;
        r[x] = l[x] = d[x] = 0;
        return Merge(L, R);
    }
    void solve(int x, int y)
    {
        int left = Pop(x), right = Pop(y);
        left = Merge(left, x);
        right = Merge(right, y);
        left = Merge(left, right);
        printf("%d
    ", Top(left));
    }
    int main()
    {
        int n, m, i, x, y;
        while(~scanf("%d", &n))
        {
            tot = 0;
            for(i=1; i<=n; ++i)
            {
                scanf("%d",&x);
                Init(x);
            }
            scanf("%d", &m);
            for(i=1; i<=m; ++i)
            {
                scanf("%d%d", &x, &y);
                int fx = findset(x), fy = findset(y);
                if(fx==fy)
                {
                    printf("-1
    ");
                }
                else
                {
                    solve(fx, fy);
                }
            }
        }
        return 0;
    }
    /*
    5
    20
    16
    10
    10
    4
    5
    2 3
    3 4
    
    8
    5
    5
    -1
    10
    */
    


  • 相关阅读:
    bzoj 2818 Gcd(欧拉函数 | 莫比乌斯反演)
    bzoj 2186 [Sdoi2008]沙拉公主的困惑(欧拉函数,逆元)
    bzoj 2393 Cirno的完美算数教室(容斥原理+搜索)
    c3p0 连接池配置
    Hibernate连接池断开自动重连
    Oracle ASM注意事项
    JAVA如何获得数据库的字段及字段类型
    在引入的css或者js文件后面加参数的作用
    JAVA注解
    Linux软连接和硬链接
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5409540.html
Copyright © 2011-2022 走看看