CF1322C Instant Noodles

CF1322C Instant Noodles - 洛谷

题面比较绕,看了题解的离谱结论:求所有点集权值和的 \(gcd\) 等价于把所有连边相同的右侧点合并之后求权值的 \(gcd\)
现在考虑怎么合并两个连边相同的右侧点。这边要积累经验,可以直接把集合放在 \(map\)\(key\) 上,将权值和作为 \(value\),然后就可以愉快地合并了。
时间复杂度 \(O(nlogn)\)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
#define int ll
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
int ans, T, n, m, c[N];
set<int> e[N];
map<set<int>, int> mp;
void solve(){
	cin >> n >> m;
	F(i, 1, n) cin >> c[i];
	F(i, 1, m){
		int u, v;
		cin >> u >> v;
		e[v].insert(u);
	}
	F(i, 1, n) if(e[i].size()) mp[e[i]] += c[i];
	for(auto x : mp) ans = __gcd(ans, x.second);
	cout << ans << '\n';
	ans = 0;
	map<set<int>, int>().swap(mp);
	F(i, 1, n) set<int>().swap(e[i]);
}
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T;
	while(T --) solve();
	return fflush(0), 0;
}
posted @ 2025-06-30 16:30  superl61  阅读(7)  评论(0)    收藏  举报