https://atcoder.jp/contests/abc183/tasks/abc183_f
裸的启发式合并
对每个连通块维护个map表示存在哪些班级的几个人就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,cnt,tot,cas,ans;
int a[maxl],c[maxl],f[maxl],sz[maxl];
map<int,int> mp[maxl];
bool vis[maxl];
char s[maxl];
inline void prework()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
f[i]=i;mp[i][c[i]]=1;sz[i]=1;
}
}
inline int find(int x)
{
if(f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
inline void mainwork()
{
for(int i=1;i<=m;i++)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
x=find(x);y=find(y);
if(x!=y)
{
if(sz[x]<sz[y])
swap(sz[x],sz[y]),swap(mp[x],mp[y]);
f[y]=x;
sz[x]+=sz[y];
for(auto it:mp[y])
mp[x][it.first]+=it.second;
}
}
else
{
x=find(x);
printf("%d\n",mp[x][y]);
}
}
}
inline void print()
{
}
int main()
{
int t=1;
//scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}