Building Block
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3315 Accepted Submission(s): 991
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.
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
Source
#include<stdio.h>
#include<iostream>
using namespace std;
int father[30005];
int high[30005];//以该点为根结点的最大高度
int low[30005];//该集合中该点下面的高度
int find(int x)
{
if(father[x]==x)
return x;
int fx=find(father[x]);
low[x]=low[father[x]]+low[x];
return father[x]=fx;
}
void init()
{
int i;
for(i=0;i<30005;i++)
{
father[i]=i;
high[i]=1;
low[i]=0;
}
}
int main()
{
int p;
char c;
scanf("%d",&p);
getchar();
init();
while(p--)
{
int x,y;
scanf("%c ",&c);
if(c=='M')
{
scanf("%d %d",&x,&y);
getchar();
int px=find(x);
int py=find(y);
if(px==py)
continue;
father[px]=py;
low[px]=high[py];
high[py]=high[px]+high[py];
}
else if(c=='C')
{
//getchar();
int k;
scanf("%d",&k);
getchar();
find(k);
printf("%d\n",low[k]);
}
}
return 0;
}