题解 P2342 【叠积木】
约翰和贝西在叠积木。共有30000块积木,编号为1到30000。一开始,这些积木放在地上,自然地分成N堆。贝西接受约翰的指示,把一些积木叠在另一些积木的上面。一旦两块积木相叠, 彼此就再也不会分开了,所以最后叠在一起的积木会越来越高。约翰让贝西依次执行P条操作,操作分为两种:
第一种是移动操作,格式为“移动X到Y的上面”。X和Y代表两块积木的编号,意思是将X所的那堆积木,整体叠放到Y所在的那堆积木之上;
第二种是统计操作,格式为“统计Z下方的积木数量”。Z代表一块积木的编号,意思是贝西需要报告在编号为Z的积木之下还有多少块积木
请编写一个程序,帮助贝西回答每条统计问题。
这题就是并查集的一个板子,这里大概不用讲了,代码放一下
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}
const int N=1e5+10;
int q,fa[N],dep[N],sz[N],x,y;
char flag;
int find(int x){
if(fa[x]==x)return x;
int tmp=find(fa[x]);
dep[x]+=dep[fa[x]];
return fa[x]=tmp;
}
int main(){
read(q);
for(int i=1;i<N;i++)fa[i]=i,sz[i]=1;
while(q--){
cin>>flag;
if(flag=='M'){
read(x);read(y);
int tx=find(x),ty=find(y);
fa[tx]=ty;
dep[tx]=sz[ty];
sz[ty]+=sz[tx];
}else{
read(x);
find(x);
cout<<dep[x]<<endl;
}
}
return 0;
}