Submission #1275160

#TimeUsernameProblemLanguageResultExecution timeMemory
1275160vk3601hSirni (COCI17_sirni)C++20
0 / 140
302 ms104168 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>
#include <climits>

using namespace std;

const int MAX_VAL = 10000000;
const int T = 1000;

vector<int> parent;

int find(int x) {
    if (parent[x] != x) {
        parent[x] = find(parent[x]);
    }
    return parent[x];
}

void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x != y) {
        parent[y] = x;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    vector<int> P(n);
    for (int i = 0; i < n; i++) {
        cin >> P[i];
    }

    sort(P.begin(), P.end());
    P.erase(unique(P.begin(), P.end()), P.end());
    int m = P.size();

    if (m == 0) {
        cout << 0 << endl;
        return 0;
    }
    if (m == 1) {
        cout << 0 << endl;
        return 0;
    }

    if (P[0] == 1) {
        cout << 0 << endl;
        return 0;
    }

    vector<int> next(MAX_VAL + 2, 0);
    vector<int> pos(MAX_VAL + 1, -1);

    for (int i = 0; i < m; i++) {
        if (P[i] <= MAX_VAL) {
            pos[P[i]] = i;
        }
    }

    for (int i = MAX_VAL; i >= 1; i--) {
        next[i] = next[i + 1];
        if (pos[i] != -1) {
            next[i] = i;
        }
    }

    parent.resize(m);
    for (int i = 0; i < m; i++) {
        parent[i] = i;
    }

    for (int i = 0; i < m; i++) {
        int a = P[i];
        for (int k = 2; (long long)k * a <= MAX_VAL; k++) {
            int target = k * a;
            if (target > MAX_VAL) break;
            if (next[target] == target) {
                int j = pos[target];
                if (j != -1) {
                    if (find(i) != find(j)) {
                        unite(i, j);
                    }
                }
            }
        }
    }

    int comps = 0;
    for (int i = 0; i < m; i++) {
        if (find(i) == i) {
            comps++;
        }
    }

    if (comps == 1) {
        cout << 0 << endl;
        return 0;
    }

    vector<tuple<int, int, int>> edges;

    for (int i = 0; i < m; i++) {
        int a = P[i];
        if (a > T) break;
        for (int k = 1; (long long)k * a <= MAX_VAL; k++) {
            int L = k * a;
            int R = (k + 1) * a - 1;
            if (L > MAX_VAL) break;
            if (next[L] == 0) continue;
            if (next[L] > R) continue;
            int b = next[L];
            int j = pos[b];
            if (j == -1) continue;
            int w = b - L;
            edges.push_back({i, j, w});
        }
    }

    for (int i = 0; i < m - 1; i++) {
        int w = P[i + 1] - P[i];
        edges.push_back({i, i + 1, w});
    }

    sort(edges.begin(), edges.end(), [](const auto& a, const auto& b) {
        return get<2>(a) < get<2>(b);
    });

    long long ans = 0;
    for (const auto& e : edges) {
        int u = get<0>(e);
        int v = get<1>(e);
        int w = get<2>(e);
        if (find(u) != find(v)) {
            ans += w;
            unite(u, v);
            comps--;
            if (comps == 1) break;
        }
    }

    cout << ans << endl;

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...