银河英雄传说

有一个划分为 NN 列的星际战场,各列依次编号为 1,2,,N1,2,…,N。

有 NN 艘战舰,也依次编号为 1,2,,N1,2,…,N,其中第 ii 号战舰处于第 ii 列。

有 TT 条指令,每条指令格式为以下两种之一:

  1. M i j,表示让第 ii 号战舰所在列的全部战舰保持原有顺序,接在第 jj 号战舰所在列的尾部。
  2. C i j,表示询问第 ii 号战舰与第 jj 号战舰当前是否处于同一列中,如果在同一列中,它们之间间隔了多少艘战舰。

现在需要你编写一个程序,处理一系列的指令。

输入格式

第一行包含整数 TT,表示共有 TT 条指令。

接下来 TT 行,每行一个指令,指令有两种形式:M i j 或 C i j

其中 MM 和 CC 为大写字母表示指令类型,ii 和 jj 为整数,表示指令涉及的战舰编号。

输出格式

你的程序应当依次对输入的每一条指令进行分析和处理:

如果是 M i j 形式,则表示舰队排列发生了变化,你的程序要注意到这一点,但是不要输出任何信息;

如果是 C i j 形式,你的程序要输出一行,仅包含一个整数,表示在同一列上,第 ii 号战舰与第 jj 号战舰之间布置的战舰数目,如果第 ii 号战舰与第 jj 号战舰当前不在同一列上,则输出 1−1。

数据范围

N30000,T500000N≤30000,T≤500000

输入样例:

4
M 2 3
C 1 2
M 2 4
C 4 2

输出样例:

-1
1
#include<bits/stdc++.h>
using namespace std;
const int N =1000000;
const int SN = 31000;
int cx,cy,qx,qy;
int n,m,T;
int s[SN],d[SN],ship[SN];
char str;
int find_set(int x){
   /*
    int r=x;
    while(s[r] != r) r=s[r];
    int i = x,j;
    while(i!=r){
        j=s[i];
        s[i]=r;
        i=j;
    }
     */
    if(s[x]!=x)
    {
        int root=find_set(s[x]);
        d[x]+=d[s[x]];
        s[x]=root;
    }
    return s[x];
}
void unionn(int x,int y){
    x=find_set(x); y=find_set(y);
    s[x]=y;
    d[x]=ship[y];
    ship[y]+=ship[x];
    return;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>T;
    for(int i=1;i<=SN;i++){
        s[i]=i;
        d[i]=0;
        ship[i]=1;
    }
    for(int i =0;i<T;i++){
        cin>>str>>cx>>cy;
        if(str=='M') {
            int dx= find_set(cx),dy = find_set(cy);
            s[dx]=dy;
            d[dx]=ship[dy];
            ship[dy]+=ship[dx];
        }
        else {
             //cout<<find_set(cx)<<" "<<find_set(cy)<<endl;
            if (find_set(cx)==find_set(cy)){
                //cout<<"M"<<" "<<d[cx]<<" "<<d[cy]<<endl;
                cout<<abs(d[cx]-d[cy])-1<<endl;
            }
            else cout<<"-1"<<endl;
        }
    }

    return 0;
}

 

posted @ 2021-05-01 12:42  limited_Infinite  阅读(78)  评论(0编辑  收藏  举报
// //返回顶部 //返回顶部按钮