The meaning of problems
It gives a bipartite graph, each of the n points on both sides, a total of m edges, n, m ≤ 5e5. Right of the dot having a weight \ (C_i \) , for the point set S contains only the left point, the definition of N ( S) is the point of all this set point set point adjacent to the right, f (S) is the weight of these points and Q. all possible f (S) is the greatest common factor.
Thinking
Consider a number of points on the right, if the left corresponding to the point where they are consistent, indicating that they must occur simultaneously in the N (S), so that they shrink to a point, the new value of the original weight and the weight. Condensing after removing those points again to the point 0 degree, the following proof gcd answer is the weight of the remaining points. mentioned later \ (c_i \) is described above has been processed.
At this time, the answer is disposed g, answers the true value of g is obviously divisible by G. All f (S), to give \ (g | G \) is provided. \ (G = K × g \) so that all. \ (C_i \ ) divided by \ (G \) . Suppose \ (K>. 1 \) , there is a \ (C_J \) , so \ (K \ C_J the nmid \) , do not constitute all disposed adjacent the point of the point the set S ', the Complete Works of points left for the U, the N (S') is not only the right point set point j included, because if there are no other points to be included, which has been shrinking point is contradictory, because \ (K | F (the U-), K \ C_J the nmid \) , so \ (K \ the nmid F (the U--S ') \) , so conflict resolution. \ (K =. 1, G = G \) .
Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i, l, r) for (int i = l; i <= r; i++)
const int maxn = 5e5 + 5;
int t, n, m, u, v;
ll c[maxn];
vector<int> g[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> t;
while (t--) {
cin >> n >> m;
inc(i, 0, n - 1) vector<int>().swap(g[i]);
inc(i, 0, n - 1) cin >> c[i];
inc(i, 0, m - 1) {
cin >> u >> v;
u--, v--;
g[v].push_back(u);
}
inc(i, 0, n - 1) sort(g[i].begin(), g[i].end());
vector<int> id(n);
iota(id.begin(), id.end(), 0);
sort(id.begin(), id.end(), [&](int a, int b) { return g[a] < g[b]; });
ll res = 0;
for (int i = 0, j; i < n; i = j) {
ll sum = 0;
j = i;
while (j < n && g[id[i]] == g[id[j]]) {
sum += c[id[j]];
j++;
}
if (g[id[i]].size()) res = __gcd(res, sum);
}
cout << res << "\n";
}
}