답안 #1092872

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1092872 2024-09-25T09:26:31 Z vjudge1 Sirni (COCI17_sirni) C++14
140 / 140
3319 ms 434732 KB
#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;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 39512 KB Output is correct
2 Correct 38 ms 42444 KB Output is correct
3 Correct 17 ms 39708 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 604 KB Output is correct
2 Correct 21 ms 40448 KB Output is correct
3 Correct 17 ms 39772 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 39516 KB Output is correct
2 Correct 16 ms 39472 KB Output is correct
3 Correct 16 ms 39724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 96 ms 17736 KB Output is correct
2 Correct 318 ms 54692 KB Output is correct
3 Correct 123 ms 30032 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 7628 KB Output is correct
2 Correct 214 ms 54432 KB Output is correct
3 Correct 94 ms 15856 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 212 ms 54684 KB Output is correct
2 Correct 439 ms 103932 KB Output is correct
3 Correct 120 ms 30140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 31 ms 7924 KB Output is correct
2 Correct 424 ms 103968 KB Output is correct
3 Correct 112 ms 30168 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 158 ms 65364 KB Output is correct
2 Correct 2392 ms 434732 KB Output is correct
3 Correct 183 ms 65460 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 155 ms 65468 KB Output is correct
2 Correct 3199 ms 434616 KB Output is correct
3 Correct 235 ms 65456 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 39 ms 42948 KB Output is correct
2 Correct 3319 ms 434480 KB Output is correct
3 Correct 128 ms 30140 KB Output is correct