Building Block
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5811 Accepted Submission(s): 1790
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<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
int city,road;
int pre[33333];
int up[33333],down[33333];
int find(int x)
{
if(x==pre[x])return x;
int tem=find(pre[x]);
down[x]=down[x]+down[pre[x]];
return pre[x]=tem;
/*int i=x,j;
while(pre[i]!=r)
{
j=pre[i];
pre[i]=r;
i=j;
} */
}
void merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
pre[fy]=fx;
}
int main(){
int n;
while(cin>>n)
{
int i;
char op[11];
int a,b;
for(i=0;i<=31015;i++)
{
pre[i]=i;
up[i]=1;
down[i]=0;
}
for(i=1;i<=n;i++)
{
cin>>op;
if(op[0]=='M')
{
scanf("%d%d",&a,&b);
int fx=find(a);
int fy=find(b);
if(fx!=fy)
{
pre[fx]=fy;
down[fx]=up[fy];
up[fy]+=up[fx];
}
}
else
{
scanf("%d",&a);
find(a);
cout<<down[a]<<endl;
}
}
}
return 0;
}