zoukankan      html  css  js  c++  java
  • bzoj 1455: 罗马游戏 左偏树+并查集

    1455: 罗马游戏

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 668  Solved: 247
    [Submit][Status]

    Description

    罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令: 1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。 2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。 皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)

    Input

    第一行一个整数n(1<=n<=1000000)。n表示士兵数,m表示总命令数。 第二行n个整数,其中第i个数表示编号为i的士兵的分数。(分数都是[0..10000]之间的整数) 第三行一个整数m(1<=m<=100000) 第3+i行描述第i条命令。命令为如下两种形式: 1. M i j 2. K i

    Output

    如果命令是Kill,对应的请输出被杀人的分数。(如果这个人不存在,就输出0)

    Sample Input

    5
    100 90 66 99 10
    7
    M 1 5
    K 1
    K 1
    M 2 3
    M 3 4
    K 5
    K 4

    Sample Output


    10
    100
    0
    66

      第一次写左偏树,还是理解了很久,可以发现,左偏树的合并和SplitMergeTree非常相似,都是维护了堆的性质,只不过左偏树在保证堆的性质的同时维护左偏的特性,而SMTree维护的是dfs序。

      左偏树合并大致为:1、按照堆的性质拼接 2、交换左右儿子以满足左偏 3、更新深度

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 1001000
    bool live[MAXN];
    int L[MAXN],R[MAXN],V[MAXN],D[MAXN];
    int uf[MAXN];
    int get_fa(int now)
    {
            return uf[now]==now ? now : uf[now]=get_fa(uf[now]);
    }
    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);
            if (D[L[x]]<D[R[x]])swap(L[x],R[x]);
            D[x]=D[R[x]]+1;
            return x;
    }
    int main()
    {
            freopen("input.txt","r",stdin);
            int x,y,z,n,m;
            scanf("%d",&n);
            for (int i=1;i<=n;i++)uf[i]=i,live[i]=true;
            for (int i=1;i<=n;i++)
            {
                    scanf("%d ",V+i);
                    D[i]=0;
            }
            scanf("%d
    ",&m);
            char opt;
            for (int i=1;i<=m;i++)
            {
                    scanf("%c",&opt);
                    if (opt=='M')
                    {
                            scanf("%d%d
    ",&x,&y);
                            if (!live[x] || !live[y])continue;
                            if (get_fa(x)==get_fa(y))continue;
                            uf[get_fa(x)]=uf[get_fa(y)]=Merge(get_fa(x),get_fa(y));
                    }else
                    {
                            scanf("%d
    ",&x);
                            if (!live[x])
                            {
                                    printf("0
    ");
                                    continue;
                            }
                            int t;
                            live[t=get_fa(x)]=false;
                            uf[t]=Merge(L[t],R[t]);
                            uf[uf[t]]=uf[t];
                            printf("%d
    ",V[t]);
                    }
            }
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    antd pro v5安装并运行完整demo的方法
    react项目运行在微信公众号
    nginx服务器上部署react项目
    毕业后,初入社会的困境和挣扎
    win10系统无法执行exe文件,解决方法
    前端学习11.14
    前端学习11.13
    Struts学习-Hibernate2
    Struts学习-Hibernate
    Struts2学习-自动
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4303169.html
Copyright © 2011-2022 走看看