Submission #623719

#TimeUsernameProblemLanguageResultExecution timeMemory
623719jophyyjhFinding Routers (IOI20_routers)C++14
99.93 / 100
2 ms340 KiB
/** * Well, if we naively do binary search per router, the score is ~70. After that, I * was thinking if we can minimize the num. of queries by "re-using" information. * use_detector() is clearly an increasing function, so * use_detector(l) = use_detector(r) * => use_detector(l) = use_detector(l+1) = ... = use_detector(r). * This means we can do some form of caching, though its efficiency is unknown. Also, * we do not know whether the grader is adaptive. * * Again, our task is to find the last point v with use_detector(v) = x (for each x). * First, check a point every x points, and call these checked points "initial pts". * Now, the "endpoints" we're finding must be between two initial points, so we can * do binary jump for each one of them. The num of steps is l/x + n * log_2(x). The * optimal x is 69, which yields at most 7557 steps (worst case). Good enough~ * * Steps needed: n/x * log(x), x = 69 (~7500 steps, for [S4]) * Implementation 1.5 */ #include <bits/stdc++.h> #include "routers.h" typedef std::vector<int> vec; const int X = 69; vec find_routers(int l, int n, int q) { if (l == 100000 && n == 1000 && q == 20000) { vec init_pt = {0}, init_ask = {0}; for (int i = X; i < l; i += X) { init_pt.push_back(i); init_ask.push_back(use_detector(i)); } init_pt.push_back(l); init_ask.push_back(n - 1); int m = init_pt.size(); vec midpoints; for (int i = 0; i < m - 1; i++) { int a = init_pt[i], b = init_pt[i + 1]; int left = init_ask[i], right = init_ask[i + 1]; while (left < right) { int j1 = a, j2 = b; while (j1 < j2) { int mid = (j1 + j2 + 1) / 2; if (use_detector(mid) == left) j1 = mid; else j2 = mid - 1; } midpoints.push_back(j1); a = j1 + 1, left++; } } vec ans = {0}; for (int mi : midpoints) ans.push_back(2 * mi - ans.back()); return ans; } else { vec ans = {0}; for (int i = 0; i < n - 1; i++) { int prev = ans.back(); int a = prev, b = l; while (a < b) { int mid = (a + b + 1) / 2; if (use_detector(mid) == i) a = mid; else b = mid - 1; } ans.push_back(2 * a - prev); } return ans; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...