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
#include <stdio.h>
int pre[30005];
int high[30005];//以该点为根节点的最大高度
int low[30005];//在该集合中在该点下面的个数
int find(int x)
{
if(pre[x] == x)
return x;
int z = find(pre[x]);
low[x] = low[pre[x]]+low[x];
return pre[x] = z;
}
void set()
{
int i;
for(i = 0; i<30005; i++)
{
pre[i] = i;
high[i] = 1;
low[i] = 0;
}
}
int main()
{
int p;
char c;
scanf("%d%*c",&p);
set();
while(p--)
{
int x,y;
scanf("%c",&c);
if(c == 'M')
{
scanf("%d%d%*c",&x,&y);
int rx,ry;
rx = find(x);
ry = find(y);
if(rx==ry)
continue;
pre[rx] = ry;
low[rx] = high[ry];
high[ry] = high[rx] + high[ry];
}
else if(c == 'C')
{
int k,i;
scanf("%d%*c",&k);
find(k);
printf("%d\n",low[k]);
}
}
return 0;
}