zoukankan      html  css  js  c++  java
  • bzoj1455 罗马游戏

    罗马游戏

    Time Limit: 5 Sec Memory Limit: 64 MB

    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的士兵的分数。
    第三行一个整数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




    stl的堆不是可并堆。。。所以我写了个左偏堆(因为好写。。。。) 这个板子有点窒息。。。。注意如果你的堆很小,有个儿子就是0,那么你的fa[0] 会被改,然后你以后可能也会用到fa[0],你就凉凉。。。。
    ```c++

    include<bits/stdc++.h>

    using namespace std;
    const int maxn = 1e6 + 10, L = 0, R = 1;
    struct lpl{
    int data, dis, son[2];
    }node[maxn];
    int n, m, fa[maxn];
    bool flag[maxn];

    namespace Left_Partial_Tree{
    int find(int t){return (t == fa[t]) ? (t) : (fa[t] = find(fa[t]));}
    int merge(int A, int B){
    if(A * B == 0) return A + B;
    if(node[A].data > node[B].data) swap(A, B);
    node[A].son[R] = merge(node[A].son[R], B);
    if(node[node[A].son[L]].dis < node[node[A].son[R]].dis) swap(node[A].son[L], node[A].son[R]);
    node[A].dis = node[node[A].son[R]].dis + 1;
    return A;
    }
    inline void pop(int t){
    t = find(t); int A = node[t].son[L], B = node[t].son[R];
    int tmp = merge(A, B); A = find(A), B = find(B);
    fa[A] = tmp; fa[B] = tmp; fa[tmp] = tmp;
    node[t].son[L] = node[t].son[R] = node[t].data = node[t].dis = 0;
    }
    }

    int main()
    {
    scanf("%d", &n); node[0].dis = -1;
    for(int i = 1; i <= n; ++i){scanf("%d", &node[i].data); fa[i] = i;}
    scanf("%d", &m); char s[21]; int x, y;
    while(m--){
    scanf("%s", s + 1);
    if(s[1] == 'M'){
    scanf("%d%d", &x, &y); if(flag[x] || flag[y]) continue;
    int A = Left_Partial_Tree::find(x), B = Left_Partial_Tree::find(y);
    if(A == B) continue;
    int F = Left_Partial_Tree::merge(A, B);
    fa[A] = F; fa[B] = F;
    }
    else{
    scanf("%d", &x); if(flag[x]){printf("0 "); continue;}
    int A = Left_Partial_Tree::find(x);
    printf("%d ", node[A].data); Left_Partial_Tree::pop(A); flag[A] = true;
    }
    fa[0] = 0;
    }
    return 0;
    }

    心如花木,向阳而生。
  • 相关阅读:
    数组中寻找和为X的两个元素
    JSP&Servlet学习笔记(一)
    自下而上的动态规划算法
    计数排序
    快速排序
    堆排序
    LeetCode-001题解
    算法不归路之最大子序列(C++版)
    算法不归路之插入排序(C版)
    互联网五层模型
  • 原文地址:https://www.cnblogs.com/LLppdd/p/9367000.html
Copyright © 2011-2022 走看看