题解:本题主要考察并查集。
简要题意:有
T
T
T条指令,有两种操作:
M
M
M指令,将第
i
i
i号所在的队列,接至第
j
j
j号战舰所在的战舰队列的尾部
C
C
C指令,第
i
i
i号战舰与第
j
j
j号战舰当前是否在同一列中,如果在同一列中,那么它们之间布置有多少战舰。
1.并查集+前缀和:用并查集来合并区间,记录区间战舰数量。
求两个点的距离的问题,便想到用前缀和来实现:
f
r
o
n
t
[
i
]
front[i]
front[i]表示飞船
i
i
i到其所在队列队头的距离,
i
i
i到
j
j
j的距离为
a
b
s
(
f
r
o
n
t
[
i
]
−
f
r
o
n
t
[
j
]
)
−
1
abs(front[i]-front[j])-1
abs(front[i]−front[j])−1
n
u
m
[
i
]
num[i]
num[i]表示以
i
i
i为队头的队列的飞船数量
代码如下:
#include<bits/stdc++.h>
using namespace std;
int f[30001],front[30001],num[30001];//bcj,到头数,队列数
int n,T;
char s;
int find(int k)
{
if(f[k]==k)return f[k];
int fa=find(f[k]);
front[k]+=front[f[k]];
return f[k]=fa;
}
int main(){
cin>>T;
for(int i=1;i<=30000;i++)
{
f[i]=i;
front[i]=0;num[i]=1;
}
for(int i=1;i<=T;i++)
{
cin>>s;
int xx,yy;
cin>>xx>>yy;
int x=find(xx);
int y=find(yy);
if(s=='M')
{
front[x]+=num[y];
f[x]=y;
num[y]+=num[x];
num[x]=0;
}
if(s=='C')
{
if(x!=y)cout<<"-1"<<endl;
else cout<<abs(front[xx]-front[yy])-1<<endl;
}
}
return 0;
}