题意:有30000个木块,编号从1到30000,然后有两种操作M a b,把木块a所在的堆块放到木块b所在的堆块上,操作C a,询问木块a下面有多少个木块。
题解:用一个数组s[i]存木块i所在堆块一共有多少个木块,因为要求木块i下面有多少个木块,所以再添加一个数组dis[i]存木块i到根节点有多少个木块,这样res = s[i]-dis[i]-1。dis数组更新放在寻找根结点递归的后面,因为要先更新父亲的再更新自己的。
#include <stdio.h>
const int N = 30005;
char str[5];
int p, pa[N], s[N], dis[N];
int get_parent(int x) {
if (x != pa[x]) {
int f = pa[x];
pa[x] = get_parent(pa[x]);
dis[x] += dis[f];
}
return pa[x];
}
int main() {
int t;
for (int i = 0; i <= N; i++) {
pa[i] = i;
s[i] = 1;
dis[i] = 0;
}
scanf("%d", &t);
while (t--) {
scanf("%s", str);
if (str[0] == 'M') {
int a, b;
scanf("%d%d", &a, &b);
int px = get_parent(a);
int py = get_parent(b);
pa[py] = px;
dis[py] = s[px];
s[px] += s[py];
}
else {
int a;
scanf("%d", &a);
int px = get_parent(a);
printf("%d\n", s[px] - dis[a] - 1);
}
}
return 0;
}