zoukankan      html  css  js  c++  java
  • 【数据结构】bzoj1455罗马游戏

    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

     
     
    =======================================华丽丽的分割线========================================
    发现自己不会写可并堆了肿么办。。。
    主要是一个merge操作,每一次选择val比较小的作为根,然后把另外一个合并进来。
    每一次通过递归的方式把另一个堆合并在右儿子,然后如果右儿子太大了就和左儿子互换,防止这棵树太不平衡。
    然后就做完辣。
    时间复杂度O(nlogn),代码如下:
     1 #include <bits/stdc++.h>
     2 #define Maxn 1000007
     3 using namespace std;
     4 int read()
     5 {
     6     int x=0,f=1;char ch=getchar();
     7     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     8     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     9     return x*f;
    10 }
    11 int n,m;
    12 int ls[Maxn],rs[Maxn];
    13 int v[Maxn];
    14 int fa[Maxn],d[Maxn];
    15 bool vis[Maxn];
    16 char ch[10];
    17 int find(int x)
    18 {
    19     if (x==fa[x]) return fa[x];
    20     fa[x]=find(fa[x]);
    21     return fa[x];
    22 }
    23 int merge(int x,int y)
    24 {
    25     if (x==0) return y;
    26     if (y==0) return x;
    27     if (v[x]>v[y]) swap(x,y);
    28     rs[x]=merge(rs[x],y);
    29     if (d[rs[x]]>d[ls[x]]) swap(ls[x],rs[x]);
    30     d[x]=d[rs[x]]+1;
    31     return x;
    32 }
    33 int main()
    34 {
    35     n=read();
    36     for (int i=1;i<=n;i++)
    37         v[i]=read();
    38     for (int i=1;i<=n;i++)
    39     {
    40         fa[i]=i;
    41         d[i]=1;
    42     }
    43     memset(vis,true,sizeof(vis));
    44     m=read();
    45     while (m--)
    46     {
    47         scanf("%s",ch);
    48         if (ch[0]=='M')
    49         {
    50             int x=read(),y=read();
    51             if ((!vis[x])||(!vis[y])) continue;
    52             int p=find(x),q=find(y);
    53             if (p!=q) fa[p]=fa[q]=merge(p,q);
    54         } else
    55         {
    56             int x=read();
    57             if (!vis[x])
    58             {
    59                 printf("%d
    ",0);
    60                 continue;
    61             }
    62             int p=find(x);
    63             vis[p]=false;
    64             printf("%d
    ",v[p]);
    65             fa[p]=merge(ls[p],rs[p]);
    66             fa[fa[p]]=fa[p];
    67         }
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    Lua中..和#运算符的用法
    C语言之linux内核实现平方根计算算法
    Xcode中git的用法介绍与&quot;Please tell me who you are&quot;问题的解决方式
    公钥加密算法究竟什么鬼
    Mesos, Marathon, Docker 平台部署记录
    查找olr备份路径
    OpenCV矩阵运算
    改动Centosserver主机名称
    HDU 1114
    C++虚函数表剖析
  • 原文地址:https://www.cnblogs.com/Tommyr7/p/7000957.html
Copyright © 2011-2022 走看看