Submission #393527

#TimeUsernameProblemLanguageResultExecution timeMemory
393527JimmyZJXThe Big Prize (IOI17_prize)C++14
20 / 100
14 ms3508 KiB
#include <iostream> #include <fstream> #include <algorithm> #include <cstring> #include <climits> #include <cassert> #include <tuple> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <string> #include <unordered_set> #include <unordered_map> #include <numeric> using namespace std; typedef long long LL; typedef vector<int> Vi; typedef vector<LL> VL; typedef vector<bool> Vb; typedef vector<vector<int>> Vii; #define forR(i, n) for (int i = 0; i < (n); i++) Vi ask(int i); int cntV = 0, N, cntNotV; int ask_cache[200003][2]; Vi askC(int i) { if (ask_cache[i][0] >= 0) { return Vi{ ask_cache[i][0], ask_cache[i][1] }; } Vi rs = ask(i); ask_cache[i][0] = rs[0]; ask_cache[i][1] = rs[1]; return rs; } int getLeftNonVCnt(int i) { int c = 0; while (true) { if (i >= N) return cntNotV - c; Vi rs = askC(i); if (rs[0] + rs[1] == cntNotV) { // is a IV node return rs[0] - c; } else { i++; c++; } } } int find_best(int n) { N = n; memset(ask_cache, -1, sizeof(ask_cache)); if (n <= 5000) { forR(i, n) { Vi rs = askC(i); if (rs[0] == 0 && rs[1] == 0) return i; } } cntV = INT_MAX; forR(i, 500) { Vi rs = askC(i); if (rs[0] == 0 && rs[1] == 0) return i; cntV = min(cntV, n - rs[0] - rs[1]); } cntNotV = n - cntV; auto getTth = [n](int t) { // goal: get the t-th non-V node int l = 0, r = n - 1; while (l < r) { int mid = (l + r) / 2; if (getLeftNonVCnt(mid + 1) >= t) { r = mid; } else { l = mid + 1; } } return l; }; int cntIV = INT_MAX; // cnt_ge_IV for (int t = 1; t <= 30; t++) { int node = getTth(t); // l is the t-th non-V node assert(getLeftNonVCnt(node) == t - 1); Vi rs = askC(node); assert(rs[0] + rs[1] < cntNotV); if (rs[0] == 0 && rs[1] == 0) return node; cntIV = min(cntIV, n - rs[0] - rs[1]); } int cntLtIV = n - cntIV; auto getLeftNonVICnt = [&getTth, cntLtIV](int i_cntV) { int c = 0; while (true) { if (i_cntV > cntNotV) return cntNotV - c; Vi rs = askC(getTth(i_cntV)); assert(rs[0] + rs[1] <= cntLtIV); if (rs[0] + rs[1] == cntLtIV) { // is a IIV node return rs[0] - c; } else { i_cntV++; c++; } } }; for (int t = 1; t <= cntLtIV; t++) { // goal: get the t-th non-IV node int l = 30, r = cntNotV; while (l < r) { int mid = (l + r) / 2; if (getLeftNonVICnt(mid + 1) >= t) { r = mid; } else { l = mid + 1; } } // l is the t-th non-IV node int node = getTth(l); Vi rs = askC(node); assert(rs[0] + rs[1] < cntLtIV); if (rs[0] == 0 && rs[1] == 0) return node; } return -1; //int l = 0, r = n - 1; //while (l < r) { // int mid = (l + r) / 2; // Vi rs = ask(mid); // if (rs[0] == rs[1]) return mid; // if (rs[0] == 1) { // r = mid - 1; // } else { // l = mid + 1; // } //} //return l; } #ifdef TEST_LOCAL Vi _answer{ 2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2 }; Vi ask(int i) { int n = _answer.size(); assert(i >= 0 && i < n); int l = 0, r = 0; for (int j = 0; j < n; j++) { if (_answer[j] < _answer[i]) { if (j < i) l++; else r++; } } return Vi{ l, r }; } int main() { _answer = Vi(6000, 3); _answer[3] = 2; _answer[3999] = _answer[5997] = _answer[5998] = 2; _answer[5999] = 1; auto r = find_best(_answer.size()); return 0; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...