从Wiking大神那学到的并查集新用法,把一个点从集合中移除的时候,不删除这个点,把它的信息剪切到一个从未出现的新的点中,
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 200010
int fa[N],id[N/2],size[N],val[N];
inline int find(int x)
{
if(fa[x]!=x) return fa[x]=find(fa[x]);
return x;
}
int n,m,op,p,q;
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<N;i++)
{
fa[i]=val[i]=i;
size[i]=1;
}
for(int i=1;i<=n;i++)
{
id[i]=i;
}
int cnt=n;
while(m--)
{
scanf("%d",&op);
if(op==3)
{
scanf("%d",&p);
int fa=find(id[p]);
printf("%d %d\n",size[fa],val[fa]);
}
else
{
scanf("%d%d",&p,&q);
if(op==1)
{
int fp=find(id[p]),fq=find(id[q]);
if(fp!=fq)
{
fa[fp]=fq;
size[fq]+=size[fp];
val[fq]+=val[fp];
}
}
else
{
int fp=find(id[p]),fq=find(id[q]);
if(fp!=fq)
{
size[fp]--;
val[fp]-=p;
id[p]=(++cnt);
fa[id[p]]=fq;
size[fq]++;
val[fq]+=p;
}
}
}
}
}
return 0;
}