1、题目大意:
john 正在玩积木,有N个积木编号为1、、、N,分成N堆,每堆只包含一个积木,然后做P次操作,操作分为2种,
M X Y:把包含X的一堆放到包含Y的一堆上,如果XY同在一堆上,不做处理
C X:计算出X积木下边有多少个积木
每次遇到C操作,输出数量
遇到的问题:
第一个:数据的n有0的点,这个是数据的问题
第二个:有一个比较隐秘的bug,如果给出两块石头,且他们已经属于一个集合的话便不要做任何操作,我就是被这个数据卡住了,这里没注意的话在poj是能够ac的
思路:用a数组记录每一个块最上面的跟,用b数组记录最下面的根;用sum数组记录每个点到所在块最上面的根的距离,然后将给出的点point求出所在块的最下面的跟point1;sun[point1]-sum[point]就是所求答案;
代码:
#include<stdio.h>
int a[30005],b[30005],sum[30005],reg[30005];
int find(int tt) //求最上面的根,并计算tt点到根的距离;
{
if(tt==a[tt])
return tt;
int t=a[tt];
a[tt]=find(a[tt]);
sum[tt]+=sum[t];
return a[tt];
}
int find1(int tt) //求出tt最下面的根;
{
if(tt!=b[tt])
{
b[tt]=find1(b[tt]);
}
return b[tt];
}
void sort(int x,int y,int za,int zb) //求出y到x的距离
{
a[y]=x;
sum[y]+=reg[x];
reg[x]=reg[x]+reg[y]; //reg函数记录每一个块点的数目,并且只有块最上面的点才记录;
reg[y]=0;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
int i,j;
char c;
int za,zb;
for(i=0;i<30005;i++)//切记从0开始
{
a[i]=i;
sum[i]=0;
b[i]=i;
reg[i]=1;
}
while(n--)
{
getchar();
scanf("%c",&c);
if(c=='M')
{
scanf("%d%d",&za,&zb);
int x=find(za);
int y=find(zb);
if(x==y) //如果给出的两个数在同一个块,则无需操作;
continue;
int tx=find1(za);
int ty=find1(zb);
b[tx]=ty;
sort(x,y,za,zb);
}
else
{
scanf("%d",&za);
int zz=find1(za);
int aa=find(za);
int bb=find(zz);
printf("%d\n",sum[zz]-sum[za]);
}
}
}
}