답안 #1024130

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1024130 2024-07-15T13:01:26 Z Thunnus Sirni (COCI17_sirni) C++17
140 / 140
1135 ms 746988 KB
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::pair;
using std::vector;

// BeginCodeSnip{DSU (from the module)}
class DisjointSets {
  private:
	vector<int> parents;
	vector<int> sizes;

  public:
	DisjointSets(int size) : parents(size), sizes(size, 1) {
		for (int i = 0; i < size; i++) { parents[i] = i; }
	}

	int find(int n) {
		return parents[n] == n ? n : (parents[n] = find(parents[n]));
	}

	bool unite(int n1, int n2) {
		n1 = find(n1);
		n2 = find(n2);
		if (n1 == n2) { return false; }
		if (sizes[n1] < sizes[n2]) { std::swap(n1, n2); }
		sizes[n1] += sizes[n2];
		parents[n2] = n1;
		return true;
	}
};
// EndCodeSnip

int main() {
	int card_num;
	std::cin >> card_num;
	vector<int> cards(card_num);
	for (int &c : cards) {
		std::cin >> c;
		assert(c >= 1);
	}

	std::sort(cards.begin(), cards.end());
	// we can erase the dupes bc modding them with the original one = 0
	cards.erase(std::unique(cards.begin(), cards.end()), cards.end());

	int largest = cards.back();  // since we sorted the cards already
	// next_largest[i] contains the index of lowest card value that's >= i
	vector<int> next_largest(largest + 1, -1);
	for (int i = 0; i < cards.size(); i++) { next_largest[cards[i]] = i; }
	for (int c = largest - 1; c >= 0; c--) {
		// if this isn't assigned yet, assign it the previous one
		if (next_largest[c] == -1) { next_largest[c] = next_largest[c + 1]; }
	}

	vector<vector<pair<int, int>>> good_links(largest + 1);
	for (int i = 0; i < cards.size() - 1; i++) {
		// get all relevant cards this card could be connected to
		good_links[cards[i + 1] % cards[i]].push_back({i, i + 1});
		for (int at = 2 * cards[i]; at <= largest; at += cards[i]) {
			int good_mod = next_largest[at];
			good_links[cards[good_mod] % cards[i]].push_back({i, good_mod});
		}
	}

	long long total_cost = 0;
	DisjointSets linked_cards(cards.size());
	for (int c = 0; c <= largest; c++) {
		for (const pair<int, int> &link : good_links[c]) {
			bool result = linked_cards.unite(link.first, link.second);
			total_cost += c * result;
		}
	}

	cout << total_cost << endl;
}

Compilation message

sirni.cpp: In function 'int main()':
sirni.cpp:54:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   54 |  for (int i = 0; i < cards.size(); i++) { next_largest[cards[i]] = i; }
      |                  ~~^~~~~~~~~~~~~~
sirni.cpp:61:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   61 |  for (int i = 0; i < cards.size() - 1; i++) {
      |                  ~~^~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 128 ms 274188 KB Output is correct
2 Correct 173 ms 302672 KB Output is correct
3 Correct 127 ms 273648 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 600 KB Output is correct
2 Correct 764 ms 668632 KB Output is correct
3 Correct 121 ms 275028 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 121 ms 274256 KB Output is correct
2 Correct 125 ms 273744 KB Output is correct
3 Correct 121 ms 274312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 73 ms 39012 KB Output is correct
2 Correct 105 ms 66892 KB Output is correct
3 Correct 70 ms 49628 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 29760 KB Output is correct
2 Correct 69 ms 51284 KB Output is correct
3 Correct 60 ms 25432 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 76 ms 50460 KB Output is correct
2 Correct 123 ms 84000 KB Output is correct
3 Correct 67 ms 47672 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 9920 KB Output is correct
2 Correct 125 ms 84888 KB Output is correct
3 Correct 69 ms 49080 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 181 ms 289076 KB Output is correct
2 Correct 812 ms 633348 KB Output is correct
3 Correct 184 ms 291876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 180 ms 293096 KB Output is correct
2 Correct 1135 ms 746988 KB Output is correct
3 Correct 276 ms 348516 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 131 ms 276844 KB Output is correct
2 Correct 964 ms 635112 KB Output is correct
3 Correct 71 ms 51272 KB Output is correct