Submission #1092872

#TimeUsernameProblemLanguageResultExecution timeMemory
1092872vjudge1Sirni (COCI17_sirni)C++14
140 / 140
3319 ms434732 KiB
#include <bits/stdc++.h>
using namespace std;

int n;
const int MAN = 1e5;
const int MAP = 1e7;

vector<int> a;
struct pi {
    int w, u, v;
};

bool cmp(pi a, pi b) {
    return a.w < b.w;
}

int par[MAN + 5];

// Khởi tạo DSU
void Init_Dsu() {
    for (int i = 0; i < n; i++) {
        par[i] = i;
    }
}

// Tìm đại diện của tập hợp có tối ưu đường đi
int fid(int x) {
    if (par[x] == x)
        return x;
    return par[x] = fid(par[x]);
}

// Hợp nhất 2 tập hợp
bool make_pair(int x, int y) {
    int u = fid(x);
    int v = fid(y);

    if (u == v)
        return false;
    par[v] = u;
    return true;
}

vector<pi> v;
int nxt[MAP + 5];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    cin >> n;
    a.resize(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    // Sắp xếp và loại bỏ các phần tử trùng nhau
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());
    
    n = a.size();  // Cập nhật lại n sau khi loại bỏ các phần tử trùng

    // Khởi tạo mảng nxt để lưu chỉ số của phần tử tiếp theo
    for (int i = 0; i < n - 1; i++) {
        nxt[a[i]] = i;
        for (int j = a[i] + 1; j < a[i + 1]; j++)
            nxt[j] = i + 1;
    }
    nxt[a[n - 1]] = n - 1;

    // Xây dựng danh sách cạnh
    for (int i = 0; i < n; i++) {
        // Thêm cạnh với phần tử tiếp theo trong mảng
        v.push_back({a[nxt[a[i] + 1]] % a[i], i, nxt[a[i] + 1]});

        // Thêm các cạnh dựa trên bội của phần tử hiện tại
        for (int mul = 2 * a[i]; mul <= a[n - 1]; mul += a[i]) {
            v.push_back({a[nxt[mul]] % a[i], i, nxt[mul]});
            // Cập nhật giá trị `mul` để tránh việc thêm cạnh trùng lặp
            mul = a[nxt[mul]] / a[i] * a[i];
        }
    }

    // Sắp xếp các cạnh theo trọng số
    sort(v.begin(), v.end(), cmp);

    // Khởi tạo DSU
    Init_Dsu();

    // Áp dụng thuật toán Kruskal
    int ans = 0;
    for (auto x : v) {
        if (make_pair(x.u, x.v))
            ans += x.w;
    }

    // Kết quả
    cout << ans;
}
#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...