이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "prize.h"
#include <algorithm>
#include <iostream>
#include <cassert>
#include <numeric>
#include <vector>
typedef long long llong;
const int MAXN = 200000 + 10;
const int INF = 1e9;
int ans, n;
std::vector <int> res;
std::pair <int,int> asked[MAXN];
inline std::pair <int,int> query(int pos)
{
assert(1 <= pos && pos <= n);
if (asked[pos].first != -1) return asked[pos];
res = ask(pos - 1);
asked[pos] = {res[0], res[1]};
if (res[0] == 0 && res[1] == 0) ans = pos;
return asked[pos];
}
int leftCnt;
int rightCnt;
int cntBig;
int binaryCnt;
int binarySearchLeft(int from, int to)
{
int l = from, r = to, mid;
while (l < r - 1)
{
mid = (l + r) / 2;
auto [left, right] = query(mid);
if (ans != 0) return 0;
if (left + right != cntBig)
{
r = mid;
continue;
}
if (left != leftCnt)
{
r = mid;
continue;
}
l = mid;
}
query(r);
leftCnt++;
return r;
}
int binarySearchRight(int from, int to)
{
int l = from, r = to, mid;
while (l < r - 1)
{
mid = (l + r) / 2;
auto [left, right] = query(mid);
if (ans != 0) return 0;
if (left + right != cntBig)
{
l = mid;
continue;
}
if (right != rightCnt)
{
l = mid;
continue;
}
r = mid;
}
query(l);
rightCnt++;
return l;
}
int find_best(int N)
{
n = N;
srand(6686889);
std::fill(asked + 1, asked + 1 + n, std::make_pair(-1, -1));
for (int i = 1 ; i <= std::min(n, 446) ; ++i)
{
query(i);
cntBig = std::max(cntBig, asked[i].first + asked[i].second);
}
for (int i = 1 ; i <= 446 ; ++i)
{
leftCnt += (asked[i].first + asked[i].second != cntBig);
}
int l = 446, r = n + 1;
while (ans == 0 && l < r - 1)
{
if (rand()%2 == 0) l = binarySearchLeft(l, r);
else r = binarySearchRight(l, r);
}
if (ans == 0 && l != 0) query(l);
if (ans == 0 && r != n + 1) query(r);
return ans - 1;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |