제출 #221084

#제출 시각아이디문제언어결과실행 시간메모리
221084emil_physmath커다란 상품 (IOI17_prize)C++17
95.29 / 100
70 ms6144 KiB
#include "prize.h" #include <algorithm> #include <iostream> #include <chrono> #include <random> #include <vector> using namespace std; #ifdef MANSON mt19937 rng(305); #else mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); #endif // MANSON namespace { const int maxN = 200000; const int mag = 1200; int n; vector<int> cache[maxN]; inline vector<int> Ask(int i) { if (cache[i].size()) return cache[i]; return cache[i] = ask(i); } int mx = 0; inline bool Cheapest(int i) { vector<int> res = Ask(i); bool f = (res[0] + res[1] >= mx); // cerr << i << " is" << (f ? " " : "n't ") << " a cheapy.\n"; return f; } int Solve(int l, int r) { static uniform_int_distribution<int> rnd(1, 2); if (rnd(rng) == 2) { while (l <= r && !Cheapest(l)) { vector<int> res = Ask(l); if (res[0] + res[1] == 0) return l; ++l; } if (l > r) return -1; int len = 1; for (int x = (1 << 17); x >= 1; x >>= 1) { int R = l + (len + x) - 1; if (R > r) continue; // if (!Cheapest(R)) continue; vector<int> res1 = Ask(l), res2 = Ask(R); if (res1[1] == res2[1]) len += x; } if (l + len <= r) return Solve(l + len, r); return -1; } while (l <= r && !Cheapest(r)) { vector<int> res = Ask(r); if (res[0] + res[1] == 0) return r; --r; } if (l > r) return -1; int len = 1; for (int x = (1 << 17); x >= 1; x >>= 1) { int L = r - (len + x) + 1; if (L < l) continue; if (!Cheapest(L)) continue; vector<int> res1 = Ask(L), res2 = Ask(r); if (res1[1] == res2[1]) len += x; } if (l <= r - len) return Solve(l, r - len); return -1; } } int find_best(int n_) { n = n_; vector<int> p(n); iota(p.begin(), p.end(), 0); shuffle(p.begin(), p.end(), rng); if (p.size() > 446) p.erase(p.begin() + 446, p.end()); for (int i: p) { vector<int> res = Ask(i); mx = max(mx, res[0] + res[1]); if (res[0] + res[1] >= 22) break; if (res[0] + res[1] == 0) return i; } vector<int> x; for (int i = 0; i * mag < n; ++i) x.push_back(i); shuffle(x.begin(), x.end(), rng); for (int i: x) { int res = Solve(i * mag, min(i * mag + mag, n - 1)); if (res != -1) return res; } }

컴파일 시 표준 에러 (stderr) 메시지

prize.cpp: In function 'int find_best(int)':
prize.cpp:107:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...