제출 #1065176

#제출 시각아이디문제언어결과실행 시간메모리
1065176ezGeometrySirni (COCI17_sirni)C++14
0 / 140
476 ms55328 KiB
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <tuple>

using namespace std;

int n;
vector<int> parent, sizes;
int cc;

void init() {
	parent.resize(n);
	sizes.resize(n, 1);

	cc = n;

	for (int i = 0; i < n; i++) {
		parent[i] = i;
	}
}

int find_set(int a) {
	if (parent[a] == a) {
		return a;
	}
	return parent[a] = find_set(parent[a]);
}

void join_set(int a, int b) {
	a = find_set(a);
	b = find_set(b);
	if (a == b) {
		return;
	}

	if (sizes[a] > sizes[b]) {
		swap(a, b);
	}

	cc--;
	parent[a] = b;
	sizes[b] += sizes[a];
}

int main() {
	cin >> n;

	set<int> q;
	int mp = 0;

	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;
		q.insert(x);
		mp = max(mp, x);
	}

	vector<int> p;

	for (int c : q) {
		p.push_back(c);
	}
	n = p.size();

	vector<tuple<int, int, int>> edges;

	for (int j = 0; j < n; j++) {
		int c = p[j];
		for (int i = c; i <= mp; i += c) {
			auto it = lower_bound(p.begin(), p.end(), i);
			edges.push_back(make_tuple(*it % c, j, it - p.begin()));
		}
	}

	sort(edges.begin(), edges.end());

	int ans = 0;
	init();

	for (auto c : edges) {
		int w, a, b;
		tie(w, a, b) = c;

		if (find_set(a) == find_set(b)) {
			continue;
		}

		join_set(a, b);
		ans += w;
		
		if (cc == 1) {
			break;
		}
	}

	cout << ans << endl;

	return 0;
}
#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...