Submission #367990

#TimeUsernameProblemLanguageResultExecution timeMemory
367990KoDFun Tour (APIO20_fun)C++17
100 / 100
370 ms21732 KiB
#include "fun.h" #include <vector> #include <algorithm> #include <iostream> template <class T> using Vec = std::vector<T>; Vec<int> createFunTour(int N, int Q) { // Step 1. find centroid (N-1 queries) int centroid = 0; Vec<int> subtree(N); subtree[0] = N; for (int i = 1; i < N; ++i) { subtree[i] = attractionsBehind(0, i); if (subtree[i] * 2 >= N && subtree[i] < subtree[centroid]) { centroid = i; } } // Step 2. compute distances from the centroid (N-1 queries) Vec<int> dist(N); for (int i = 0; i < N; ++i) { if (i != centroid) { dist[i] = hoursRequired(centroid, i); } } // Step 3. find direct children of the centroid (0 queries) Vec<int> children; for (int i = 0; i < N; ++i) { if (dist[i] == 1) { children.push_back(i); } } // Step 4. classify vertices (at most 2N-2 queries) Vec<int> belong(N, (int) children.size() - 1); for (int i = 0; i < (int) children.size() - 1; ++i) { const auto root = children[i]; for (int u = 0; u < N; ++u) { if (u != centroid && dist[u] > hoursRequired(root, u)) { belong[u] = i; } } } // Step 5. construct a fun tour (0 queries) Vec<int> ret; ret.reserve(N); Vec<Vec<int>> vertices(children.size()); for (int i = 0; i < N; ++i) { if (i != centroid) { vertices[belong[i]].push_back(i); } } for (auto &vec: vertices) { std::sort(vec.begin(), vec.end(), [&](const int i, const int j) { return dist[i] < dist[j]; }); } const auto farthest = [&](const int i) { return vertices[i].empty() ? -1 : dist[vertices[i].back()]; }; const auto select_max = [&](const int avoid) { int select = -1, score = -1; for (int i = 0; i < (int) children.size(); ++i) { if (i != avoid) { const auto tmp = farthest(i); if (score < tmp) { select = i; score = tmp; } } } return select; }; int pivot = -1, last = -1, remain = N; while (true) { for (int i = 0; i < (int) children.size(); ++i) { if (2 * ((int) vertices[i].size()) == remain) { pivot = i; } } if (pivot != -1) { break; } const auto select = select_max(last); ret.push_back(vertices[select].back()); vertices[select].pop_back(); last = select; remain -= 1; } if (ret.size() >= 2) { const auto u = ret[ret.size() - 1]; const auto v = ret[ret.size() - 2]; if (belong[v] != pivot && dist[v] > dist[u]) { ret.pop_back(); vertices[belong[u]].push_back(u); } } while (true) { if (vertices[pivot].empty()) { break; } ret.push_back(vertices[pivot].back()); vertices[pivot].pop_back(); const auto select = select_max(pivot); if (select == -1) { break; } ret.push_back(vertices[select].back()); vertices[select].pop_back(); } ret.push_back(centroid); return ret; }
#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...