#include using namespace std; #define rep(i, from, to) for (int i = from; i < (to); ++i) #define trav(a, x) for (auto& a : x) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef vector vi; const double inf = 1e100; const int POPULATION = 10'000'000; const int ROUNDS = 50; const int MIN_RES = 100; const int MAX_RES = 5'000'000; const double GUESS_GRANULARITY = 0.02; int main() { cin.sync_with_stdio(false); cin.exceptions(cin.failbit); // For performance reasons, only consider a few (exponentially spaced) // candidate answers. vector> cands; int minGuess = (int)(MIN_RES * 2 - 1); int maxGuess = (int)(MAX_RES * 0.5 + 1); int r = minGuess; for (;;) { cands.push_back({0.0, r}); if (r == maxGuess) break; r = max((int)(r * (1 + GUESS_GRANULARITY)), r + 1); r = min(r, maxGuess); } vector lfact(POPULATION + 1); rep(i,0,POPULATION+1) lfact[i] = lgamma(i + 1); rep(it,0,ROUNDS+1) { int guess = max_element(all(cands))->second; if (it == ROUNDS) { cout << "estimate " << guess << endl; break; } // (1-guess/POPULATION)^sample = 0.5 int sample = (int)(log(0.5) / log(1 - (double)guess/POPULATION)); // int sample = (int)(POPULATION / guess); cout << "test " << sample << endl; int res; cin >> res; for (auto& cand : cands) { int k = cand.second; double logprob; int healthy = POPULATION - k; // logprob = prob(negative result) if (sample > healthy) { logprob = -inf; } else { logprob = lfact[healthy] - lfact[healthy - sample] - lfact[POPULATION] + lfact[POPULATION - sample]; } if (res) { double prob = exp(logprob); if (prob >= 1) logprob = -inf; // log(0) else logprob = log1p(-prob); // log(1 - prob) } cand.first += logprob; } } exit(0); }