Cube Stacking

Cube Stacking

Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations: 
moves and counts. 
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y. 
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.

Write a program that can verify the results of the game.

Input

* Line 1: A single integer, P

* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a ‘M‘ for a move operation or a ‘C‘ for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.

Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.

Output

Print the output from each of the count operations in the same order as the input file.

Sample Input

6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

Sample Output

1
0
2

并查集:ran[x] 表示 在x下面的立方体数,sum[x]表示x所在堆的总立方体数,随着立方体的叠放,sum值只记载在根节点处,在unite()中,ran值也只是记载在fx上,容易理解ran[fx] += sum[fy];在之后find()中再将一个个节点经行更新ran[x] += ran[fx];

#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn = 3e4+5;
using namespace std;
int pre[maxn];
int ran[maxn];
int sum[maxn];
void init(){
    for(int i = 1; i <= maxn; i++){
        pre[i] = i;
        ran[i] = 0;
        sum[i] = 1;
    }
}
int find(int x){
    if(pre[x] == x)
        return pre[x];
    int fx = pre[x];
    pre[x] = find(pre[x]);
    ran[x] += ran[fx];
    return pre[x];
}
void unite(int x,int y){
    int fx = find(x);
    int fy = find(y);
    pre[fx] = fy;
    ran[fx] += sum[fy];
    sum[fy] += sum[fx];
}
int main(){
    int p,x,y;
    char ch[2];
    init();
    scanf("%d",&p);
    while(p--){
        scanf("%s",ch);
        if(ch[0] == ‘M‘){
            scanf("%d%d",&x,&y);
            unite(x,y);
        }
        else {
            scanf("%d",&x);
            int tep = find(x);
            printf("%d\n",ran[x]);
        }
    }
    return 0;
}

另外,通过这道题终于懂了并查集的find()函数,原来我之前都是一知半解= =!

举个例子说明一下:  

int find(int x){
    if(pre[x] == x)
        return pre[x];
    int fx = pre[x];
    pre[x] = find(pre[x]);
    ran[x] += ran[fx];
    return pre[x];
}1 -> 2 -> 3 -> 4 -> 5;x = 1, fx = 2; -> x = 2, fx = 3; -> x = 3, fx = 4; -> x = 4, fx = 5; -> x = 5, fx = 5;

pre[4] = pre[5](5); -> pre[3] = pre[4](5); -> pre[2] = pre[3](5); -> pre[1] = pre[2](5);

ran[4] += ran[5];   ->  ran[3] += ran[4];   ->  ran[2] += ran[3];    -> ran[1] += ran[2];

这样就形成了一颗高度为2的树,除根节点外全部节点指向根节点,搜索起来减少了不少的复杂度,膜拜!而ran值也在其中是从根节点经行更新;并查集真是so cool!
时间: 2024-10-26 22:06:34

Cube Stacking的相关文章

POJ 1988 Cube Stacking

Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 18820   Accepted: 6530 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start w

poj.1988.Cube Stacking(并查集)

Cube Stacking Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1988 Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They st

加权并查集——(POJ1988)Cube Stacking

Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 25647   Accepted: 8975 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start w

HDU 1988 Cube Stacking (数据结构-并查集)

Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 18900   Accepted: 6568 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start w

POJ 1988 Cube Stacking(并查集+路径压缩)

题目链接:id=1988">POJ 1988 Cube Stacking 并查集的题目 [题目大意] 有n个元素,開始每一个元素自己 一栈.有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈. 另外一种操作是询问含有x元素以下有多少个元素. 用sum数组储存每一个栈中的元素个数.每次合并的时候将sum加到 父亲节点.也就是每一个栈的最底部. 用under数组储存当前节点以下有多少元素.每次合并的时候,就能够将顶端元素的under赋值为父节点也就是栈最底部的sum. void U

HDU 1988 Cube Stacking (数据结构-并检查集合)

Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 18834   Accepted: 6535 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start w

POJ 1988 Cube Stacking(转)

这道题的思路,就是每次记下该点到父结点的个数,并记录下其下的结点个数.之后,每次"C"时,将总的减去它所压的方块,即答案!!!(也是参考别人的~-?) <pre name="code" class="cpp">#include<stdio.h> #include<iostream> using namespace std; #define max 30010 struct node { int parent;/

poj1988 Cube Stacking(并查集

题目地址:http://poj.org/problem?id=1988 题意:共n个数,p个操作.输入p.有两个操作M和C.M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[1 6]上为[2 4 1 6]),C x为输出x下面有几个数. 思路:并查集每个集合以栈最下面的数为根,维护两个数组num[x]表示x所在集合节点总数,count[x]表示x下方节点个数.每次查找压缩路径的时候更新count(换父节点的时候每轮都把父节点的count加给儿子,就可以一直更新到x所在栈

Cube Stacking POJ1988 【并查集的应用】

http://poj.org/problem?id=1988 Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P