[ABC329F] Colored Ball
题面翻译
给定 N N N 个盒子,每个盒子里面有一个颜色为 C i C_i Ci 的小球。有 Q Q Q 次操作,每次操作将第 a i a_i ai 个盒子中的球都放到第 b i b_i bi 个盒子里面,你需要在每次操作后输出当前操作结束后第 b i b_i bi 个盒子里面有多少个不同颜色的小球。
如果盒子为空,输出 0 0 0 即可。
输入格式
入力は以下の形式で標準入力から与えられる。ここで、 $ \text{query}_i $ は $ i $ 番目のクエリを意味する。
$ N $ $ Q $ $ C_1 $ $ C_2 $ $ \ldots $ $ C_N $ $ \text{query}_1 $ $ \text{query}_2 $ $ \vdots $ $ \text{query}_Q $
各クエリは次の形式で与えられる。
$ a $ $ b $
输出格式
$ Q $ 行出力せよ。 $ i $ 行目には $ i $ 番目のクエリに対する答えを出力せよ。
样例 #1
样例输入 #1
6 5
1 1 1 2 2 3
1 2
6 4
5 1
3 6
4 6
样例输出 #1
1
2
1
1
3
样例 #2
样例输入 #2
5 3
2 4 2 4 2
3 1
2 5
3 2
样例输出 #2
1
2
0
启发式合并:让小的并到大的上面
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll>PII;
typedef pair<ll, string>PIS;
const int N = 2e5 + 10;
const int MOD = 998244353;
const int INF = 0X3F3F3F3F;
const int dx[] = {-1, 1, 0, 0, -1, -1, +1, +1};
const int dy[] = {0, 0, -1, 1, -1, +1, -1, +1};
const int M = 1e9 + 7;
ll a[N];
ll p[N];
set<ll>se[N];
ll finds(ll x)
{
if(x != p[x]) p[x] = finds(p[x]);
return p[x];
}
int main()
{
int n, q;
cin >> n >> q;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
se[i].insert(a[i]);
}
//启发式合并:优先遍历更小的数组
while(q --){
ll l, r;
cin >> l >> r;
if(se[l].size() < se[r].size())
{
for(auto it : se[l])
{
se[r].insert(it);
}
se[l].clear();
}
else {
for(auto it : se[r])
{
se[l].insert(it);
}
se[r].clear();
swap(se[r], se[l]);
}
cout << se[r].size() << endl;
}
return 0;
}