제출 #316244

#제출 시각아이디문제언어결과실행 시간메모리
316244MrDomino커다란 상품 (IOI17_prize)C++14
100 / 100
58 ms15620 KiB
#include <bits/stdc++.h>
#include "prize.h"

using namespace std;

mt19937 rng((long long) (new char));
const int N = 200000 + 7;
vector<int> ret[N];
set<int> s[N];
set<int> sums;
int sol;
int pos;

vector<int> get(int i) {
  if (ret[i].empty()) {
    ret[i] = ask(i);
    if (ret[i][0] == 0 && ret[i][1] == 0) {
      sol = i;
    }
  }
  sums.insert(ret[i][0] + ret[i][1]);
  s[ret[i][0] + ret[i][1]].insert(i);
  return ret[i];
}

int rep(int l, int r) {
  if (l > r) {
    return 0;
  }
  for (auto &x : sums) {
    auto it = s[x].lower_bound(r);
    if (it != s[x].end()) {
      auto it2 = s[x].lower_bound(l + 1);
      if (it2 != s[x].begin()) {
        it2--;
        int f = *it2;
        int s = *it;
        if (get(f)[0] == get(s)[0]) {
          return 0;
        }
      }
    }
  }
  int m = (l + r) / 2;
  if (get(m)[0] == 0 && get(m)[1] == 0) {
    return m;
  }
  if (rng() & 1) {
    int x = rep(m + 1, r);
    if (x == 0) {
      x = rep(l, m - 1);
    }
    return x;
  } else {
    int x = rep(l, m - 1);
    if (x == 0) {
      x = rep(m + 1, r);
    }
    return x;
  }
}

int find_best(int n) {
  sol = -1;
  vector<int> ord(n);
  for (int i = 0; i < n; i++) {
    ord[i] = i;
  }
  shuffle(ord.begin(), ord.end(), rng);
  while ((int) ord.size() > 447) {
    ord.pop_back();
  }
  for (auto &x : ord) {
    get(x);
  }
  if (sol != -1) {
    return sol;
  }
  return rep(0, n - 1);
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...