题意:

给定一串数字,每个数字初始在对应大小的列上,现在有两种操作:

  1. M i j,将j位置上的数字放在i列的最下方
  2. C i j,若i和j不在一列,输出-1,若i和j在同一列,则输出他们之间相差的数字个数。
     
     

分析:

并查集,维护时继承子节点的节点大小用于判断相差的数目。

 
 

代码:

#include <bits/stdc++.h>
using namespace std;
constexpr int mod = 1e9 +7;
//constexpr int mod2 = 998244353;
constexpr int MAXNe5 = 1e5 +7;
constexpr int MAXNe6 = 1e6 + 7;
typedef long long ll;
#pragma region 
inline long long read() {
    char c = getchar();long long flag = 1, ans = 0;
    while(c < '0' || c > '9'){if(c == '-') flag = -1; c = getchar();}
    while(c >= '0' && c <= '9'){ans = ans * 10 + c - '0'; c = getchar();}
    return (ans * flag);
}
#pragma endregion
// C'est la vie
int fa[MAXNe6], dis[MAXNe6], sz[MAXNe6];
void init() {
    for(int i = 0; i < MAXNe6; ++ i) 
        fa[i] = i, dis[i] = 0, sz[i] = 1;
}

int find(int x) {
    if(x == fa[x]) return x;
    int rt = find(fa[x]);
    dis[x] += dis[fa[x]];
    return fa[x] = rt;
}

void merge(int x, int y) {
    x = find(x);
    y = find(y);
    fa[x] = y;
    dis[x] = sz[y];
    sz[y] += sz[x];
}

int main() {
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    init();
    while(t --) {
        char opt;
        int x, y;
        cin >> opt >> x >> y;
        if(opt == 'M') {
            merge(x, y);
        } else {
            // cout << find(x) << ' ' << find(y) << endl;
            if(find(x) != find(y)) cout << -1 << endl;
            else cout << abs(dis[x] - dis[y]) - 1 << endl;
        }

    }
    #ifndef ONLINE_JUDGE
    system("pause");
    #endif
}