Building Block


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

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


/*
2818 带权并查集
题意:
有N个积木编号为1、、、N,分成N堆,每堆只包含一个积木,然后做P次操作,操作分为2种,
M X Y:把包含X的一堆放到包含Y的一堆上,如果XY同在一堆上,不做处理
C X:计算出X积木下边有多少个积木
每次遇到C操作,输出数量

up[x]表示x上有多少个元素
sum[x]表示这一堆总的数目
*/
#include<iostream>
#include<stdio.h>
using namespace std;
#define N 30010

int pre[N],up[N],sum[N];

void init()
{
int i;
for(i=0;i<N;i++)
{
pre[i]=i;
sum[i]=1;
up[i]=0;
}
}

int find(int x)
{
int t;
if(x!=pre[x])
{
t=find(pre[x]);
up[x]+=up[pre[x]];
pre[x]=t;
}
return pre[x];
}

void merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
pre[fy]=fx;
up[fy]=sum[fx];
sum[fx]+=sum[fy];
}
}
int main()
{
int n,a,b;
char ch[2];

// freopen("test.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
init();
while(n--)
{
scanf("%s",ch);
if(ch[0]=='M')
{
scanf("%d%d",&a,&b);
merge(a,b);
}
else
{
scanf("%d",&a);
b=find(a);
printf("%d\n",sum[b]-up[a]-1);
}
}
}
}