답안 #736765

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
736765 2023-05-06T08:02:26 Z GrindMachine Sirni (COCI17_sirni) C++17
140 / 140
3453 ms 779516 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
https://oj.uz/submission/715977 (for optimizations)


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];
    }
};

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];
    }

    vector<pii> here[N];

    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;

            if (first / v == k) {
                int w = 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 212 ms 274368 KB Output is correct
2 Correct 316 ms 306740 KB Output is correct
3 Correct 216 ms 274688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 244 ms 274376 KB Output is correct
2 Correct 1790 ms 700908 KB Output is correct
3 Correct 296 ms 275120 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 219 ms 274484 KB Output is correct
2 Correct 251 ms 274328 KB Output is correct
3 Correct 218 ms 274484 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 340 ms 291864 KB Output is correct
2 Correct 457 ms 317708 KB Output is correct
3 Correct 366 ms 303008 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 231 ms 277236 KB Output is correct
2 Correct 367 ms 299884 KB Output is correct
3 Correct 337 ms 290032 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 443 ms 302812 KB Output is correct
2 Correct 520 ms 337128 KB Output is correct
3 Correct 403 ms 299960 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 261 ms 280636 KB Output is correct
2 Correct 583 ms 337700 KB Output is correct
3 Correct 423 ms 301952 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 412 ms 294940 KB Output is correct
2 Correct 2201 ms 663904 KB Output is correct
3 Correct 405 ms 298720 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 398 ms 299600 KB Output is correct
2 Correct 3453 ms 779516 KB Output is correct
3 Correct 658 ms 359160 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 265 ms 277924 KB Output is correct
2 Correct 2577 ms 664276 KB Output is correct
3 Correct 422 ms 302760 KB Output is correct