题意:有两种操作:一个是M,a,b;表示a集合所有的元素,置于b集合之上;
二是C ,a;表示a集合下的元素的个数有多少个;
此题;要构造两个数组,一个是rank【i】,他记录的是i集合元素的总个数;另一个是under【i】,记录的是i元素下的个数,这个集合要更新,在并查集里进行更新 ,他会从k一直更新到他的父节点,这样其中的所有的点便都有了因随时操作所引起的元素个数的变化;
在合并的时候,都合并到第二个集合上;这样保证了这个集合的父节点正好位于最下边,则有under【m】=rank【n】;
在操作c是一定要再次更新一次即find(m);保证结果的正确性;
#include"stdio.h"
#include"string.h"
int pre[100006],rank[100006];
int under[100006];
int find(int k)//合并的同时,也更新了under;
{
int temp;
if(k!=pre[k])
{
temp=find(pre[k]);
under[k]+=under[pre[k]];
pre[k]=find(pre[k]);
}
return pre[k];
}
int main()
{
int m,n,i,k;
char a[10];
while(scanf("%d",&k)!=EOF)
{
for(i=0;i<=k;i++)
{
pre[i]=i;
rank[i]=1;
under[i]=0;
}
while(k--)
{
scanf("%s",a);
if(a[0]=='M')
{
scanf("%d%d",&m,&n);
m=find(m);
n=find(n);
if(m!=n)
{
pre[m]=n;
under[m]=rank[n];
rank[n]+=rank[m];
}
}
else
{
scanf("%d",&m);
find(m);
printf("%d\n",under[m]);
}
}
}
return 0;
}