luogu P1196 [NOI2002]银河英雄传说

题目传送门: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的绝对值)

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页