Submission #1360771

#TimeUsernameProblemLanguageResultExecution timeMemory
1360771turnejaSirni (COCI17_sirni)C++20
140 / 140
4316 ms590608 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

#define endl "\n"
#define ll long long
#define IOS ios_base::sync_with_stdio(false); cin.tie(nullptr);

const int N = 1e7 + 5;

int parent[N];
int sz[N];

int head[N];

struct Edge {
    int u, v, nxt;
};

vector<Edge> edges;

void add_edge(int w, int u, int v) {
    edges.push_back({u, v, head[w]});
    head[w] = (int)edges.size() - 1;
}

int dsu_find(int a) {
    if (parent[a] == a) {
        return a;
    }
    return parent[a] = dsu_find(parent[a]);
}

void dsu_unite(int a, int b) {
    if (sz[b] > sz[a]) {
        swap(a, b);
    }
    sz[a] += sz[b];
    parent[b] = a;
}

int main() {
    IOS;
    int n, m = 0;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        m = max(m, a[i]);
    }
    vector<int> freq(m + 1, 0), nx(m + 1, 0);
    iota(parent, parent + m + 1, 0);
    fill(sz, sz + m + 1, 1);
    fill(head, head + m + 1, -1);

    for (int i = 0; i < n; i++) {
        freq[a[i]] = 1;
    }
    int last = m + 1;
    for (int i = m; i > 0; i--) {
        if (freq[i]) {
            last = i;
        }
        nx[i] = last;
    }
    for (int i = 1; i <= m; i++) {
        if (!freq[i]) {
            continue;
        }
        int lastk = -1;
        int k = (i + 1 > m ? m + 1 : nx[i + 1]);
        if (k <= m) {
            add_edge(k % i, i, k);
            lastk = k;
        }
        for (int j = 2 * i; j <= m; j += i) {
            int k = nx[j];
            if (nx[j] > m) {
                break;
            }
            if (k == lastk) {
                continue;
            }
            add_edge(k % i, i, k);
            lastk = k;
        }
    }
    ll ans = 0;
    for (int i = 0; i <= m; i++) {
        for (int e = head[i]; e != -1; e = edges[e].nxt) {
            int u = edges[e].u, v = edges[e].v;
            u = dsu_find(u), v = dsu_find(v);
            if (u != v) {
                ans += i;
                dsu_unite(u, v);
            }
        }
        head[i] = -1;
    }
    cout << ans << endl;

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