#LA 3027 Corporative Network [并查集]
#Description
有n个点,一开始都是孤立的,然后有I,E两种操作
I u v,把u的父节点设为v,距离为abs(u-v) % 1000,保证u之前没有父节点
E 询问u到父节点的距离
#Algorithm
带权并查集
v[i]表示i节点到根节点的距离,E就是问这个
find()里面就是要把v[p] += v[t] 因为最后路径压缩了
unite()这个函数不写也行,直接把id[u] = v; v[u] = abs(u - v) % 1000就好了
#Code
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MOD = 1000;
const int MAXN = 20000 + 9;
int id[MAXN];
int v[MAXN];
int n;
void init()
{
for (int i = 0; i < n; i++) {
id[i] = i;
v[i] = 0;
}
}
int find(int p)
{
if (p != id[p]) {
int t = id[p];
id[p] = find(id[p]);
v[p] += v[t];
}
return id[p];
}
void unite(int p, int q)
{
//int i = find(p), j = find(q);
id[p] = q;
v[p] = abs(p - q) % MOD;
}
void solveE()
{
int u;
scanf("%d\n", &u);
find(u - 1);
//cout << 'E' << u << endl;
printf("%d\n", v[u - 1]);
}
void solveI()
{
int u, v;
scanf("%d%d\n", &u, &v);
unite(u - 1, v - 1);
//cout << 'I' << u << v << endl;
}
void solve()
{
scanf("%d\n", &n);
init();
for (;;) {
char ch;
cin >> ch;
if (ch == 'O') break;
if (ch == 'E') solveE(); else solveI();
}
}
int main()
{
// freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--) {
solve();
}
}