题意:
给定一串数字,每个数字初始在对应大小的列上,现在有两种操作:
- M i j,将j位置上的数字放在i列的最下方
- 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 }