Codeforces 1322C - Instant Noodles(数学)

Topic Link

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";
    }
}

Guess you like

Origin www.cnblogs.com/hs-zlq/p/12566671.html