Submission #1272907

#TimeUsernameProblemLanguageResultExecution timeMemory
1272907flaming_top1Sirni (COCI17_sirni)C++20
112 / 140
5114 ms606124 KiB
#include <bits/stdc++.h>

#define SPED                                                                                                           \
    ios_base::sync_with_stdio(false);                                                                                  \
    cin.tie(0);                                                                                                        \
    cout.tie(0);

#define endl "\n"
#define fi first
#define se second
#define lint long long
#define fami signed
#define lore main
#define freefire freopen
#define Data tuple<lint, int, int>

const lint INF = 0x1f1f1f1f1f1f1f1f;
const lint NEG = 0xE1E1E1E1E1E1E1E1;

using namespace std;

int mx;
int n, idx[10000005], near[10000005], N, sz[100005], par[100005];
lint a[100005];
vector<int> diff;
vector<Data> edges;


void setup()
{
    for (int i = 1; i <= N; i++)
    {
        sz[i] = 1;
        par[i] = i;
    }
}

int find_par(int now)
{
    return par[now] == now ? now : par[now] = find_par(par[now]);
}

void combine(int l, int r)
{
    l = find_par(l);
    r = find_par(r);
    if (l == r)
        return;
    if (sz[l] < sz[r])
        swap(l, r);
    par[r] = l;
    sz[l] += sz[r];
}

void sang()
{
    for (int i = 1; i <= mx; i++)
    {
        if (idx[i])
            for (int j = i * 2; j <= mx; j += i)
                if (idx[j])
                    combine(idx[i], idx[j]);
    }
}

fami lore()
{
    SPED;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        diff.emplace_back(a[i]);
    }
    diff.emplace_back(-1);
    sort(diff.begin(), diff.end());
    diff.erase(unique(diff.begin(), diff.end()), diff.end());
    N = diff.size() - 1;

    for (int i = 1; i <= N; i++)
        idx[diff[i]] = i;

    mx = diff.back();

    setup();

    sang();

    lint mst = 0;

    for (int i = mx; i >= 1; i--)
    {
        near[i] = near[i + 1];
        if (idx[i])
            near[i] = i;
    }

    for (int i = 1; i <= N; i++)
    {
        lint val = diff[i]; // giá trị thực của đỉnh i
        for (lint j = val; j <= mx; j += val)
        {
            lint l = j + 1, r = min(j + val - 1, (lint)mx);
            if (near[l] <= r)
            {
                int v = idx[near[l]];
                if (v)
                    edges.emplace_back(near[l] - j, i, v); // hoặc near[l] % val
            }
        }
    }
    sort(edges.begin(), edges.end());
    for (auto [w, u, v] : edges)
    {
        if (find_par(u) != find_par(v))
        {
            mst += w;
            combine(u, v);
        }
    }
    cout << mst;
}
// Let your soul wander where dreams are born.
#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...