답안 #736754

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
736754 2023-05-06T07:55:44 Z GrindMachine Sirni (COCI17_sirni) C++17
140 / 140
4170 ms 780180 KB
// Om Namah Shivaya

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
#define pb push_back
#define endl '\n'
#define sz(a) a.size()
#define setbits(x) __builtin_popcountll(x)
#define ff first
#define ss second
#define conts continue
#define ceil2(x, y) ((x + y - 1) / (y))
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define yes cout << "Yes" << endl
#define no cout << "No" << endl

#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep1(i, n) for(int i = 1; i <= n; ++i)
#define rev(i, s, e) for(int i = s; i >= e; --i)
#define trav(i, a) for(auto &i : a)

template<typename T>
void amin(T &a, T b) {
    a = min(a, b);
}

template<typename T>
void amax(T &a, T b) {
    a = max(a, b);
}

#ifdef LOCAL
#include "debug.h"
#else
#define debug(x) 42
#endif

/*

refs:
edi
https://codeforces.com/blog/entry/50241?#comment-341912


i still dont understand the proof

*/

const int MOD = 1e9 + 7;
const int N = 1e7 + 5;
const int inf1 = int(1e9) + 5;
const ll inf2 = ll(1e18) + 5;

struct DSU {
    vector<int> par, rankk, siz;

    DSU() {

    }

    DSU(int n) {
        init(n);
    }

    void init(int n) {
        par = vector<int>(n + 1);
        rankk = vector<int>(n + 1);
        siz = vector<int>(n + 1);
        rep(i, n + 1) create(i);
    }

    void create(int u) {
        par[u] = u;
        rankk[u] = 0;
        siz[u] = 1;
    }

    int find(int u) {
        if (u == par[u]) return u;
        else return par[u] = find(par[u]);
    }

    bool same(int u, int v) {
        return find(u) == find(v);
    }

    void merge(int u, int v) {
        u = find(u), v = find(v);
        if (u == v) return;

        if (rankk[u] == rankk[v]) rankk[u]++;
        if (rankk[u] < rankk[v]) swap(u, v);

        par[v] = u;
        siz[u] += siz[v];
    }
};

vector<pii> here[N];

void solve(int test_case)
{
    int n; cin >> n;
    vector<int> a(n + 5);
    rep1(i, n) cin >> a[i];

    map<int, int> mp;
    vector<pii> b;
    DSU dsu(n + 5);

    rep1(i, n) {
        if (mp.count(a[i])) {
            dsu.merge(i, mp[a[i]]);
        }
        else {
            b.pb({a[i], i});
            mp[a[i]] = i;
        }
    }

    vector<int> nxt(N, -1);
    for (auto [v, ind] : b) {
        nxt[v] = ind;
    }

    rev(i, N - 2, 1) {
        if (nxt[i] == -1) nxt[i] = nxt[i + 1];
    }

    for (auto [v, ind1] : b) {
        rep1(k, (N - 1) / v) {
            int first = k * v;
            if (k == 1) first++;
            int ind2 = nxt[first];
            if (ind2 == -1) break;

            int w = min(a[ind1] % a[ind2], a[ind2] % a[ind1]);
            here[w].pb({ind1, ind2});
        }
    }

    ll ans = 0;
    rep(w, N) {
        for (auto [u, v] : here[w]) {
            if (!dsu.same(u, v)) {
                ans += w;
                dsu.merge(u, v);
            }
        }
    }

    cout << ans << endl;
}

int main()
{
    fastio;

    int t = 1;
    // cin >> t;

    rep1(i, t) {
        solve(i);
    }

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 174 ms 274556 KB Output is correct
2 Correct 283 ms 306692 KB Output is correct
3 Correct 174 ms 274708 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 169 ms 274368 KB Output is correct
2 Correct 1727 ms 701140 KB Output is correct
3 Correct 178 ms 275148 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 172 ms 274500 KB Output is correct
2 Correct 177 ms 274308 KB Output is correct
3 Correct 173 ms 274596 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 287 ms 292576 KB Output is correct
2 Correct 436 ms 318328 KB Output is correct
3 Correct 332 ms 303716 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 203 ms 277424 KB Output is correct
2 Correct 341 ms 300356 KB Output is correct
3 Correct 268 ms 290732 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 361 ms 303488 KB Output is correct
2 Correct 482 ms 337708 KB Output is correct
3 Correct 326 ms 300584 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 205 ms 280928 KB Output is correct
2 Correct 543 ms 338304 KB Output is correct
3 Correct 341 ms 302688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 351 ms 295836 KB Output is correct
2 Correct 2051 ms 664768 KB Output is correct
3 Correct 382 ms 299496 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 365 ms 300268 KB Output is correct
2 Correct 4170 ms 780180 KB Output is correct
3 Correct 608 ms 359924 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 211 ms 278108 KB Output is correct
2 Correct 3728 ms 664836 KB Output is correct
3 Correct 322 ms 303428 KB Output is correct