• 【洛谷】P2713 罗马游戏


    题目地址:

    https://www.luogu.com.cn/problem/P2713

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

    输入格式:
    第一行一个整数 n n n,表示士兵数。
    第二行 n n n个整数 a 1 , a 2 , … a n a_1,a_2,\ldots a_n a1,a2,an,其中 a i a_i ai表示编号为 i i i的士兵的分数。
    第三行一个整数 m m m
    3 + i 3+i 3+i行描述第i条命令。命令为如下两种形式:M i jK i

    输出格式:
    如果命令是K i,对应的请输出被杀士兵的分数(如果这个人不存在,就输出 0 0 0)。

    数据范围:
    对于 100 % 100\% 100%的数据, 1 ≤ n ≤ 1 0 6 1\le n\le 10^6 1n106 1 ≤ m ≤ 1 0 5 1\le m\le 10^5 1m105 0 ≤ a i ≤ 1 0 7 0\le a_i\le 10^7 0ai107,注意测试数据中M i j i , j i,j i,j可能在同一个团中。

    可以用左偏树,参考https://blog.csdn.net/qq_46105170/article/details/126204599。代码如下:

    #include 
    using namespace std;
    
    const int N = 1e6 + 10;
    int n, m;
    int v[N], d[N], l[N], r[N];
    int p[N];
    
    int find(int x) {
      if (p[x] != x) p[x] = find(p[x]);
      return p[x];
    }
    
    int merge(int x, int y) {
      if (!x || !y) return x ^ y;
      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() {
      v[0] = 2e9;
      scanf("%d", &n);
      for (int i = 1; i <= n; i++) {
        scanf("%d", &v[i]);
        p[i] = i;
        d[i] = 1;
      }
    
      scanf("%d", &m);
      while (m--) {
        char op;
        int x, y;
        cin >> op >> x;
        if (op == 'M') {
          cin >> y;
          if (!d[x] || !d[y]) continue;
          x = find(x), y = find(y);
          if (x == y) continue;
          if (v[x] > v[y]) swap(x, y);
          p[y] = x;
          merge(x, y);
        } else {
          if (!d[x]) {
            puts("0");
            continue;
          }
          x = find(x);
          d[x] = 0;
          printf("%d\n", v[x]);
          if (v[l[x]] > v[r[x]]) swap(l[x], r[x]);
          p[x] = p[l[x]] = l[x];
          merge(l[x], r[x]);
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    每次操作时间复杂度 O ( log ⁡ n ) O(\log n) O(logn),空间 O ( n ) O(n) O(n)

  • 相关阅读:
    天龙八部科举答题问题和答案(全8/8)
    MySQL的存储过程
    Maven 私服Nexus的搭建教程windows(搭配android maven插件使用)
    大模型日报|今日必读的7篇大模型论文
    mongodb简单部署
    【HCIE】14.IPV6基础
    wps/word中字体安装教程
    【Java-LangChain:使用 ChatGPT API 搭建系统-2】语言模型,提问范式与 Token
    HELM NAMED TEMPLATES practical operation
    找出缺失和重复的数字 - (LeetCode)
  • 原文地址:https://blog.csdn.net/qq_46105170/article/details/126209585