제출 #361553

#제출 시각아이디문제언어결과실행 시간메모리
361553KoD커다란 상품 (IOI17_prize)C++17
0 / 100
104 ms5864 KiB
#include "prize.h"
#include <vector>
#include <utility>
#include <algorithm>
#include <queue>
#include <set>

template <class T>
using Vec = std::vector<T>;

int find_best(int N) {
  std::set<int> lower;
  Vec<Vec<int>> memo(N);
  const auto query = [&](const int i) -> const Vec<int>& {
    if (memo[i].empty()) {
      memo[i] = ask(i);
    }
    return memo[i];
  };
  int L = 0;
  while (L < N) {
    lower.insert(query(L)[0] + query(L)[1]);
    L += 1;
    if (lower.size() == 5) {
      break;
    }
    const auto x = *lower.rbegin();
    if (x + x * x + 1 > N - L) {
      break;
    }
  }
  const auto max = *lower.rbegin();
  std::set<int> pos;
  for (int i = 0; i < L; ++i) {
    if (query(i)[0] + query(i)[1] < max) {
      pos.insert(i);
    }
  }
  std::queue<std::pair<int, int>> que;
  que.emplace(L, N - 1);
  Vec<int> left_count(N + 1, -1);
  left_count[N] = max;
  left_count[L - 1] = (int) pos.size();
  const auto count = [&](const int l, const int r) {
    return (left_count[r + 1] == -1 ? query(r + 1)[0] : left_count[r + 1]) - (left_count[l - 1] == -1 ? query(l - 1)[0] : left_count[l - 1]);
  };
  while (!que.empty() && (int) pos.size() < max) {
    const auto [l, r] = que.front();
    que.pop();
    if (l > r) {
      continue;
    }
    if (count(l, r) == 0) {
      continue;
    }
    const auto mid = (l + r) / 2;
    auto nr = mid - 1;
    auto nl = mid;
    while (nl <= r) {
      if (query(nl)[0] + query(nl)[1] == max) {
        break;
      }
      else {
        pos.insert(nl);
        nl += 1;
      }
    }
    if (nl == r + 1) {
      while (nr >= l) {
        if (query(nr)[0] + query(nr)[1] == max) {
          break;
        }
        else {
          pos.insert(nr);
          nr -= 1;
        }
      }
      que.emplace(l, nr - 1);
    }
    else {
      left_count[mid] = query(nl)[0] - (nl - mid);
      que.emplace(l, mid - 1);
      que.emplace(nl + 1, r);
    }
  } 
  for (const auto x: pos) {
    if (query(x)[0] + query(x)[1] == 0) {
      return x;
    }
  }
  return -1;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...