这个题属于并查集的变形,有3种操作:
1.合并a,b两个集合。
2.将a元素放到b集合中
3.查找a元素中的个数以及集合所有元素的和。
用并查集做就可以,只是需要记录sum以及num,然后设置一个位置数组就行。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=500001;
int n,m,p[maxn],sum[maxn],num[maxn],pos[maxn];
void Init()
{
for(int i=0;i<=n;i++)
{
p[i]=sum[i]=pos[i]=i;
num[i]=1;
}
}
int find(int x)
{
if(p[x]==x)
return x;
return p[x]=find(p[x]);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
Init();
while(m--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int ita,itb;
scanf("%d%d",&ita,&itb);
int x=find(pos[ita]);
int y=find(pos[itb]);
if(x==y)
continue;
sum[x]+=sum[y];
num[x]+=num[y];
sum[y]=num[y]=0;
p[y]=x;
}
else if(op==2)
{
int ita,itb;
scanf("%d%d",&ita,&itb);
int x=find(pos[ita]);
int y=find(pos[itb]);
if(x==y)
continue;
sum[y]+=ita;
num[y]++;
sum[x]-=ita;
num[x]--;
pos[ita]=++n;
sum[pos[ita]]=ita;
num[pos[ita]]=1;
p[pos[ita]]=y;
}
else
{
int ita;
scanf("%d",&ita);
printf("%d %d\n",num[find(pos[ita])],sum[find(pos[ita])]);
}
}
}
return 0;
}