#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAX_N 30005
#define MAX_P 100005
int n;
char operator1[MAX_P];
//par[x]==x,表示x是这个集合的根,par[i]==j,意识是i这个节点的父亲节点是j
int par[MAX_N];
//表示以i为跟的集合共有多少个元素
int total[MAX_N];
//rank[i]表示的是i在这个集合中的位置
int rank[MAX_N];
//完成初始化操作
void init(int n)
{
for(int i=0;i<n;i++)
{
par[i]=i;
total[i]=1;
rank[i]=0;
}
}
int find(int x)
{
if(par[x]==x)
return x;
else
{
//寻找根节点
int t=par[x];
par[x] =find(par[x]);
//x的位置不断后退。
rank[x] +=rank[t];
return par[x];
}
}
void unite(int a,int b)
{
int p1=find(a);
int p2=find(b);
if(p1==p2)
return ;
//是将p2合并到p1中去
//p2的位置就是total【p1】的总数
rank[p2]=total[p1];
total[p1]+=total[p2];
par[p2]=p1;
}
int main()
{
cin>>n;
int a,b;
init(MAX_N);
for(int i=0;i<n;i++)
{
cin>>operator1[i];
if(operator1[i]=='M')
{
cin>>a>>b;
//将a,b 合并,b合并于a
unite(a,b);
}
if(operator1[i]=='C')
{
cin>>a;
//首先找到a所属的这个集合共有多少个元素,再减去a的排名,即就是a的下方还有多少个元素
printf("%d\n",total[find(a)]-rank[a]-1);
}
}
}
题意:有许多箱子 1--N,你可以有两种操作,1,将x组移动至y组上方,2,查看y组下方的x值,
难点在于怎么记录这个值,用个rank[i]数组表示,i在整个集合中的位置,序列,那么total[find(a)]-rank[a]-1就是所需要的值