zoukankan      html  css  js  c++  java
  • Building Block[HDU2818]

    Building Block

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5426 Accepted Submission(s): 1663


    Problem Description
    John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:

    M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
    C X : Count the number of blocks under block X

    You are request to find out the output for each C operation.

    Input
    The first line contains integer P. Then P lines follow, each of which contain an operation describe above.

    Output
    Output the count for each C operations in one line.

    Sample Input
    6
    M 1 6
    C 1
    M 2 4
    M 2 6
    C 3
    C 4

    Sample Output
    1
    0
    2

    路径压缩的并查集。对每个点x,rank[x]记录到父亲的距离,size[x]表示以x为根节点的子树大小。x下边的积木数=x的最高级父亲father的size-Σ(从x到father的路径上各点的rank)。路径压缩这里写的有点意识模糊,居然一遍AC,提交完自己都挺奇怪,这就过了啊......

    #include <stdio.h>
    #include <string.h>
    int tmpx;
    int size[30005], rank[30005];
    class Union_Find_Set {
    #define MAX_UNION_FIND_SET_SIZE 30005
    public:
        int setSize;
        int father[MAX_UNION_FIND_SET_SIZE];
        Union_Find_Set() {
            setSize = 0;
        }
        Union_Find_Set(int x) {
            setSize = x;
            clear(x);
        }
        void clear(int x) {
            for (int i = 0; i < x; i++) {
                father[i] = i;
            }
        }
        int getFather(int x) {
            tmpx = 0;
            int ret = x, tmp;
            while (ret != father[ret]) {
                tmpx += (rank[ret]);
                ret = father[ret];
            }
            int tmpz = tmpx;
            while (x != father[x]) {
                tmp = father[x];
                father[x] = ret;
                tmpz -= rank[x];
                rank[x] += tmpz;
                x = tmp;
            }
            return ret;
        }
        bool merge(int a, int b) {
            a = getFather(a);
            b = getFather(b);
            if (a != b) {
                father[b] = a;
                rank[b] = size[a] + 1;
                size[a] += (size[b] + 1);
                return true;
            } else {
                return false;
            }
        }
        int countRoot() {
            int ret = 0;
            for (int i = 0; i < setSize; i++) {
                if (father[i] = i) {
                    ret++;
                }
            }
            return ret;
        }
    };
    
    Union_Find_Set ufs;
    int main() {
        int n, a, b;
        char q;
        while (scanf("%d", &n) != EOF) {
            memset(size, 0, sizeof(size));
            memset(rank, 0, sizeof(rank));
            ufs.clear(30001);
            while (n--) {
                getchar();
                scanf("%c", &q);
                if (q == 'M') {
                    scanf("%d%d", &a, &b);
                    ufs.merge(a, b);
                } else if (q == 'C') {
                    scanf("%d", &a);
                    printf("%d
    ", size[ufs.getFather(a)] - tmpx);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    CSP2019-S2总结
    #期望dp#洛谷 6835 [Cnoi2020]线形生物
    #树状数组,概率,离散,双指针#洛谷 6834 [Cnoi2020]梦原
    #容斥,倍数,排列组合#洛谷 2714 四元组统计
    #莫队,bitset#洛谷 3674 小清新人渣的本愿
    #贪心#洛谷 3173 [HAOI2009]巧克力
    #树链剖分,LCA#洛谷 3398 仓鼠找sugar
    #树状数组,哈希#洛谷 6687 论如何玩转 Excel 表格
    小甲鱼Python第八讲课后习题
    小甲鱼Python第七讲课后习题
  • 原文地址:https://www.cnblogs.com/dramstadt/p/6323284.html
Copyright © 2011-2022 走看看