제출 #221593

#제출 시각아이디문제언어결과실행 시간메모리
221593rama_pangICC (CEOI16_icc)C++14
100 / 100
183 ms640 KiB
#include "icc.h" #include <bits/stdc++.h> using namespace std; mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count()); vector<vector<int>> components; int Query(vector<int> A, vector<int> B) { if (A.empty() || B.empty()) return 0; return query(A.size(), B.size(), A.data(), B.data()); } int QueryComponent(vector<int> A, vector<int> B) { vector<int> P, Q; for (auto i : A) { for (auto j : components[i]) { P.emplace_back(j); } } for (auto i : B) { for (auto j : components[i]) { Q.emplace_back(j); } } return Query(P, Q); } void Answer(int A, int B) { return setRoad(A, B); } int Split(int L, int R, vector<int> &A, vector<int> &B, int depth, bool Check) { if (depth == 0) { int mid = (L + R) / 2; for (int i = L; i <= mid; i++) A.emplace_back(i); for (int i = mid + 1; i <= R; i++) B.emplace_back(i); return max(mid - L + 1, R - mid); } int mid = (L + R) / 2; if (Check) { return max(Split(L, mid, A, B, depth - 1, Check), Split(mid + 1, R, A, B, depth - 1, Check)); } else { vector<int> tA, tB; Split(L, mid, tA, tB, depth - 1, true); if (QueryComponent(tA, tB)) { return Split(L, mid, A, B, depth - 1, Check); } else { return Split(mid + 1, R, A, B, depth - 1, Check); } } } pair<int, int> BinarySearch(vector<int> A, vector<int> B, bool onComponent) { pair<int, int> res = {-1, -1}; { int lo = 0, hi = A.size() - 1; while (lo < hi) { int mid = (lo + hi) / 2; vector<int> halfA; for (int i = 0; i <= mid; i++) { halfA.emplace_back(A[i]); } int res = (onComponent ? QueryComponent(halfA, B) : Query(halfA, B)); if (res) { hi = mid; } else { lo = mid + 1; } } res.first = A[lo]; } { int lo = 0, hi = B.size() - 1; while (lo < hi) { int mid = (lo + hi) / 2; vector<int> halfB; for (int i = 0; i <= mid; i++) { halfB.emplace_back(B[i]); } int res = (onComponent ? QueryComponent(halfB, A) : Query(halfB, A)); if (res) { hi = mid; } else { lo = mid + 1; } } res.second = B[lo]; } return res; } void MergeComponent(int C1, int C2) { vector<int> Merged; for (auto i : components[C1]) Merged.emplace_back(i); for (auto i : components[C2]) Merged.emplace_back(i); components[C1].clear(); components[C2].clear(); sort(begin(components), end(components), [&](const vector<int> &a, const vector<int> &b) { return a.size() > b.size(); }); while (components.back().empty()) components.pop_back(); components.emplace_back(Merged); } void run(int N) { for (int i = 1; i <= N; i++) { components.emplace_back(vector<int>{i}); } for (int i = 1; i < N; i++) { shuffle(begin(components), end(components), rnd); vector<int> A, B; // find two components that are connected by new edge for (int depth = 0; ; depth++) { int sz = Split(0, components.size() - 1, A, B, depth, true); if (sz == 1) break; int res = QueryComponent(A, B); A.clear(), B.clear(); if (res) { Split(0, components.size() - 1, A, B, depth, false); break; } } // Binary Search to find edge's endpoint auto TwoComp = BinarySearch(A, B, true); auto Edge = BinarySearch(components[TwoComp.first], components[TwoComp.second], false); Answer(Edge.first, Edge.second); MergeComponent(TwoComp.first, TwoComp.second); } }
#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...