一个需要维护附加信息的并查集。需要维护的信息为某编号为 x 的积木下方有多少块积木。直接维护需要更新一棵树的所有节点,这显然是不方便的。
在这里我们选择让根节点保存某个编号下的箱子总数,然后下面被连接的根节点保存其下方有多少箱子。这样查询某个编号的箱子下面的箱子个数只需要向上将除了根节点之外的数量全部加起来即可。

#include <bits/stdc++.h>


using namespace std;
struct node {
    int pos;
    int num;//数量,代表总数量或者
    int high;//高度
};
const int maxn = 30000+1;
node a[maxn];

int inquiry(int x) {
    int ans = 0;
    while (a[x].pos!=x) {
        ans += a[x].num;
        x = a[x].pos;
    }
    return ans;
}

int find(int x) {
    while (a[x].pos!=x) {
        x = a[x].pos;
    }
    return x;
}

//合并操作
void Merge(int x, int y) {
    //首先寻找根节点,题目保证不会位于同一列,所以不需要判断是否根节点相等
    int root1 = find(x);
    int root2 = find(y);
    int temp = a[root2].num;
    a[root2].num = a[root1].num+a[root2].num;
    a[root1].num = temp;
    //高度不需要更新,将root1连接到root2下面
    a[root1].pos = root2;
}

int main() {
    //直接拉到最大
    for (int i=1;i<=maxn;i++) {
        //先让根节点为他本身
        a[i] = {i, 1, 1};
    }
    int q;
    int x, y;
    char c;
    cin>>q;
    while (q--) {
        cin>>c;
        if (c=='M') {
            cin>>x>>y;
            Merge(x, y);
        }
        if (c=='C') {
            cin>>x;
            cout<<inquiry(x)<<endl;
        }
    }
    
    
    return 0;
}