#include<iostream> #include<cstring> #include<cstdio> using namespace std; int root[30005],all[30005],tail[30005]; int find(int c){ if(root[c]==c) return c; int ori=find(root[c]); tail[c]+=tail[root[c]]; //压缩路径时可能会改变当前结点所指向的祖先结点,所以要同步更新当前结点的tail[] root[c]=ori; return ori; } void check(int a,int b){ int ra,rb; ra=find(a); rb=find(b); if(ra==rb) return; tail[ra]=all[rb]; all[rb]+=all[ra]; root[ra]=rb; //定义祖先结点为当前stack最底层的cube,那么a所在的stack堆在b所在的stack上形成一个新stack,新stack祖先结点为b的祖先结点rb,并且修改使ra指向rb } int main(){ int n; char ope[3]; int up,down,got; int i; for(i=0;i<=30000;i++){ root[i]=i; //root[]指向祖先结点,对于本题祖先结点定义为当前stack的最底下一个cube比较好解 tail[i]=0; //第i个结点距离祖先结点的距离,即第i个cube下面的cube个数 all[i]=1; //以结点i为祖先结点的所有结点个数,对于本题祖先结点是一个stack最底层的cube } scanf("%d",&n); while(n--){ scanf("%s",ope); if(ope[0]=='M'){ scanf("%d%d",&up,&down); check(up,down); } else if(ope[0]=='C'){ scanf("%d",&got); int nodo=find(got); //路径压缩,确保root[]指向了祖先结点 printf("%d\n",tail[got]); } } return 0; }