题目传送门:https://www.luogu.org/problemnew/show/P1196
题意:
有n个操作。
[1]M x y表示将x所在列的所有元素接在y列后;
[2]C x y如果x和y不在同一列,输出-1;否则输出x~y中有多少个元素。
思路:
并查集。
详见代码。
代码:
#include<cstdio>
#include<cmath>
#include<cstdlib>
int n;
int fa[30010],p[30010],size[30010];
/*
fa[i]表示i的祖先
p[i]表示i前面有多少艘战舰
size[i]表示i所属列的长度
*/
int find(int x)
{
if(x==fa[x]) return x;
int t=find(fa[x]);
p[x]+=p[fa[x]];//跟新当前点前面战舰的数量
return fa[x]=t;
}
int main()
{
char s[5];
int x,y;
scanf("%d",&n);
for(int i=1;i<=30000;i++)
fa[i]=i,p[i]=0,size[i]=1;
for(int i=1;i<=n;i++)
{
scanf("%s %d %d",s+1,&x,&y);
int t1=find(x),t2=find(y);//找到t1、t2的祖先,M操作一定处理的是祖先
if(s[1]=='M')
{
p[t1]+=size[t2];//将t1接在t2后,t1前面的战舰数自然多了size[t2]个
fa[t1]=t2;//合并t1、t2
size[t2]+=size[t1];//将t1接在t2后,新t2的长度自然长了size[t1]个
size[t1]=0;//将t1接在t2后,新的t1的长度就变为了0
}
else
{
printf("%d\n",t1!=t2?-1:abs(p[x]-p[y])-1);//不在同一列,即x、y的祖先不同,结果为-1,否则为后者(详见下图)
}
}
}
附图:
我们求1~5的中战舰的个数(看图可知为3)。
可知5-1-1=3
则推出ans=|x-y|-1(其中|a|表示a的绝对值)