启发式合并听起来挺高端,但好像只是一种基础的合并思想(?)
将小的集合中的数都加到大的集合中去,一般用一个map进行维护
一.并查集与启发式合并
1.[ABC183F] Confluence
#include<bits/stdc++.h>
using namespace std;
#define qio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
typedef long long ll;
typedef double db;
const int N = 2e5 + 10;
int pre[N], a[N];
map<int, int> mp[N];//第i个学生的小组中,j班学生的个数
int root(int x){
return pre[x] = (pre[x] == x ? x : root(pre[x]));
}
void merge(int u, int v){
pre[root(u)] = root(v);
}
bool isCon(int u, int v){
return root(u) == root(v);
}
void solve() {
int n, q; cin >> n >> q;
for(int i = 1; i <= n; i++){
cin >> a[i];
pre[i] = i;
mp[i][a[i]] = 1;
}
while(q--){
int op, x, y; cin >> op >> x >> y;
if(op == 1){
int xx = root(x), yy = root(y);
if(xx == yy) continue;
if(mp[xx].size() > mp[yy].size()) swap(xx, yy);
for(pair<int, int> i : mp[xx]){
mp[xx][i.first] = 0, mp[yy][i.first] += i.second;
}
pre[xx] = yy;
}else{
cout << mp[root(x)][y] << '\n';
}
}
}
signed main() {
qio
int T = 1;
// cin >> T;
while (T--) solve();
}