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.
刚学并查集,搞了好长时间才搞明白,under数组中每个元素代表与父节点之间的盒子个数,因为要路径压缩,所以需要将压缩的点更新under值。
#include<bits/stdc++.h>
using namespace std;
const int MAX=30000;
int par[MAX+5], cnt[MAX+5], under[MAX+5];
void init(){
for(int i=0; i<=MAX; i++){
par[i]=i;
cnt[i]=1;
under[i]=0;
}
}
int fin(int x){
if(par[x]==x) return x;
int temp=par[x];
par[x]=fin(par[x]);
under[x]+=under[temp];
return par[x];
}
void unite(int x, int y){
x=fin(x);
y=fin(y);
if(x==y) return;
par[x]=y;
under[x]=cnt[y];
cnt[y]+=cnt[x];
}
int main(){
int n;
scanf("%d", &n);
init();
while(n--){
char c;
getchar();
scanf("%c", &c);
if(c=='M'){
int a, b;
scanf("%d%d", &a, &b);
unite(a, b);
}
else{
int a;
scanf("%d", &a);
fin(a);
printf("%d\n", under[a]);
}
}
return 0;
}