Submission #220100

#TimeUsernameProblemLanguageResultExecution timeMemory
220100rama_pangMinerals (JOI19_minerals)C++14
100 / 100
73 ms4272 KiB
#include "minerals.h" #include <bits/stdc++.h> using namespace std; const int MAXN = 43000; const int TOTAL_QUERIES = 999976; int optimal_pivot(int n) { static vector<pair<int, int>> optimal(MAXN + 1, make_pair(1e8, 1e8)); static bool computed = false; if (computed) return optimal[n].second; computed = true; optimal[0] = optimal[1] = {0, 0}; for (int i = 2; i <= MAXN; i++) { int lo = 1, hi = i / 2; while (lo < hi) { int m1 = (lo + hi) / 2; int m2 = m1 + 1; int c1 = optimal[m1].first + optimal[i - m1].first + i - 1 + m1; int c2 = optimal[m2].first + optimal[i - m2].first + i - 1 + m2; if (c1 < c2) { hi = m1; } else { lo = m2; } } optimal[i] = make_pair(optimal[lo].first + optimal[i - lo].first + lo + i - 1, lo); } return optimal_pivot(n); } bool query(int x) { static int query_cnt = 0; static int last = -1; query_cnt++; assert(query_cnt <= TOTAL_QUERIES); int cur = Query(x); bool res = (cur == last); last = cur; return res; } void Solve(vector<int> A, vector<int> B, bool isBInside) { int n = A.size(); if (n == 0) return; if (n == 1) return Answer(A[0], B[0]); int piv = optimal_pivot(n); vector<int> Aleft, Aright; vector<int> Bleft, Bright; if (isBInside) { // All of B is in the box, so we remove the second half for (int i = 0; i < n - piv; i++) { Bleft.emplace_back(B[i]); } for (int i = n - piv; i < n; i++) { Bright.emplace_back(B[i]); query(B[i]); // } } else { // None of B is in the box, so we add the first half for (int i = 0; i < piv; i++) { Bleft.emplace_back(B[i]); query(B[i]); // add elemens in B such that only the first half remains } for (int i = piv; i < n; i++) { Bright.emplace_back(B[i]); } } for (int i = 0; i < n; i++) { if (Aright.size() == Bright.size()) { Aleft.emplace_back(A[i]); // all A[i] in the right half is matched } else if (Aleft.size() == Bleft.size()) { Aright.emplace_back(A[i]); // all A[i] in the left half is matched } else if (query(A[i])) { Aleft.emplace_back(A[i]); // A[i] has a match is in the first half of B } else { Aright.emplace_back(A[i]); // A[i] has a match in the second half of B } } return Solve(Aleft, Bleft, true), Solve(Aright, Bright, false); } void Solve(int N) { vector<int> A, B; for (int i = 1; i <= 2 * N; i++) { if (query(i)) { // the current element is already in the box B.emplace_back(i); } else { // the current element is a new element A.emplace_back(i); } } return Solve(A, B, true); }
#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...