제출 #830173

#제출 시각아이디문제언어결과실행 시간메모리
830173MathandskiSirni (COCI17_sirni)C++14
98 / 140
2332 ms786432 KiB
#include <bits/stdc++.h> 
using namespace std;
#define pb push_back 
#define is insert
#define ll long long
#define V vector
#define MS multiset
#define PL pair<ll, ll>
#define F first
#define S second
#define PQ priority_queue
#define f0r(i, begin, end) for (ll i = begin; i < end; i ++) 
#define For(i, end, begin) for (ll i = end; i > begin; i --) 
#define all(x) x.begin(), x.end()
#define INF 1000000000000000000
#define inf 1000000000
#define MOD 1000000009
#define len(x) (ll)x.size()
#define fileread(file) ifstream fin; fin.open((string)file + ".in"); ofstream fout; fout.open((string)file + ".out")
#define fastio ios_base::sync_with_stdio(0); cin.tie(nullptr)
template<typename T> istream& operator>>(istream& in, V<T>& a) {for(auto &x : a) in >> x; return in;};
template<typename T> ostream& operator<<(ostream& out, V<T>& a) {for(auto &x : a) out << x << ' '; return out;};

struct DSU {
	vector<ll> e;
	DSU(ll N) { e = vector<ll>(N, -1); }

	// get representive component (uses path compression)
	ll get(ll x) { return e[x] < 0 ? x : e[x] = get(e[x]); }

	bool same_set(ll a, ll b) { return get(a) == get(b); }

	ll size(ll x) { return -e[get(x)]; }

	bool unite(ll x, ll y) {  // union by size
		x = get(x), y = get(y);
		if (x == y) return false;
		if (e[x] > e[y]) swap(x, y);
		e[x] += e[y];
		e[y] = x;
		return true;
	}
};

ll N, ans = 0;
set<ll> nums;
ll decomp[10000001];
vector<tuple<ll, ll, ll>> edges;

void krustal () {
    ll tot = N - 1;
    DSU dsu(N);
    sort(all(edges));
    for (auto e : edges) {
        if (dsu.unite(get<1>(e), get<2>(e))) {
            ans += get<0>(e);
            if ((--tot) == 0) break;
        }
    }
}

int main () {
    cin >> N;
    DSU dsu(N);
    f0r (i, 0, N) {
        ll a; cin >> a;
        nums.is(a);
    }
    ll i = 0;
    for (auto n : nums) {
        decomp[n] = (i ++);
    }

    for (auto n : nums) {
        auto pos = nums.lower_bound(n + 1);
        ll factor = 1;
        while (pos != nums.end()) {
            if ((*pos) / n > factor) {
                factor = (*pos) / n;
            }
            edges.pb({(*pos) % n, decomp[n], decomp[*pos]});
            pos = nums.lower_bound((++factor) * n);
        }
    }
    
    krustal();
    cout << ans << endl;
}
#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...