这道题在做之前看了一下题目的提示说是并查集,而且之前也做过很类似的题,想了一下也挺有思路的就直接写了,结果就因为一开始没看清楚题目说明导致数组越界RE了一次,改了一下就直接AC了,终于不用看题解就能写出来了,感觉又有点信心了。这题就需要维护每个点的两个权值,一个是栈底元素所在栈里面元素的个数,还有就是在每个元素下面元素的个数。每次更新的时候就找到两个栈底的元素更新一下权值然后执行合并操作。在查询的时候也更新一下每个元素下面的元素个数,查询的时候执行完find函数后输出就行了。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int pa[30005],dis[30005],num[30005];
char str[2];
int find(int k)
{
if(pa[k]==k)
return k;
else
{
int t=find(pa[k]);
dis[k]+=dis[pa[k]];
pa[k]=t;
return pa[k];
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=30000;i++)
{
dis[i]=0;
pa[i]=i;
num[i]=1;
}
while(n--)
{
scanf("%s",str);
if(str[0]=='M')
{
int x,y;
scanf("%d%d",&x,&y);
int t1=find(x),t2=find(y);
dis[t1]=num[t2];
num[t2]+=num[t1];
pa[t1]=t2;
}
else
{
int x;
scanf("%d",&x);
find(x);
printf("%d\n",dis[x]);
}
}
}