# | Submission time | Handle | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
484634 | 2021-11-04T23:08:07 Z | SansPapyrus683 | Sirni (COCI17_sirni) | C++17 | 0 ms | 0 KB |
#include <iostream> #include <cassert> #include <vector> #include <algorithm> using std::cout; using std::endl; using std::vector; using std::pair; 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 get_ultimate(int n) { return parents[n] == n ? n : (parents[n] = get_ultimate(parents[n])); } bool link(int n1, int n2) { n1 = get_ultimate(n1); n2 = get_ultimate(n2); if (n1 == n2) { return false; } if (sizes[n1] < sizes[n2]) { std::swap(n1, n2); } sizes[n1] += sizes[n2]; parents[n2] = n1; return true; } }; /** * https://oj.uz/problem/view/COCI17_sirni * 4 * 2 * 6 * 3 * 11 should output 1 */ 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 = *std::max_element(cards.begin(), cards.end()); 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); vector<pair<int, pair<int, int>>> good_links; for (int i = 0; i < cards.size() - 1; i++) { 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]) { total_cost += c * linked_cards.link(link.first, link.second); } } cout << total_cost << endl; }