题意:给出编号为1 - n堆的石头堆,初始每个石头堆中都有一块石头。然后有两个操作,M x y,表示的是将x石头堆堆在y石头堆上,C x 表示的是查询x石头堆下面有多少块石头。注意如果是移动第x堆的话,和他在一起的一起移动。如果是移动到第y堆,那么直接在第y堆最上面放,原来的不变。
PS:题意理解了许久许久。
思路:用两个数组,d数组表示的是在这堆下面的石头有多少块,num数组表示的是在这堆上面以及这堆的石头个数。
这样的话。num数组是向下更新,d数组是向上更新。
比如是M x y,那么将x整堆放在y堆上,首先y层最低层yy的上面的石头个数增大,num[yy] += num[xx],(xx = finds(x),yy = finds(y))。那么向上更新是通过finds函数对d数组进行更新。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200000 + 10;
int fa[maxn];
int d[maxn];
int num[maxn];
void Init()
{
for(int i = 0; i < maxn; i ++)
fa[i] = i,d[i] = 0,num[i] = 1;
}
int finds(int x)
{
if(fa[x] != x)
{
int pre = fa[x];
fa[x] = finds(fa[x]);
d[x] += d[pre];
return fa[x];
}
return x;
}
int main()
{
int n;
while( ~ scanf("%d",&n))
{
Init();
for(int i = 1; i <= n; i ++)
{
char s[3];int x,y;
scanf("%s%d",s,&x);
int xx = finds(x);
if(s[0] == 'M')
{
scanf("%d",&y);
int yy = finds(y);
if(xx != yy)
{
fa[xx] = yy;
d[xx] = num[yy];
num[yy] += num[xx];
}
}
else
{
printf("%d\n",d[x]);
}
}
}
return 0;
}