This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#ifndef ARTHUR_LOCAL
#include "prize.h"
#endif
using namespace std;
// NB: ask(i) returns a two-elem vector<int>
const int MAXN=200000;
bool asked[MAXN];
pair<int,int> answers[MAXN];
#ifdef ARTHUR_LOCAL
vector<int> real_deal;
vector<int> ask(int n)
{
int ans1=0;
int ans2=0;
for(int i=0; i<n; i++)
{
if(real_deal[i]<real_deal[n]) ans1++;
}
for(int i=n; i<8; i++)
{
if(real_deal[i]<real_deal[n]) ans2++;
}
return {ans1,ans2};
}
#endif
pair<int,int> get_ans(int n)
{
//cout << n << endl;
if(asked[n]) return answers[n];
asked[n]=1;
vector<int> cur = ask(n);
answers[n] = {cur[0],cur[1]};
return answers[n];
}
int find_best(int n)
{
// query 30 random places in order to determine the minimum thing
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(1,1000000000);
int max_side=0;
for(int i=0; i<30; i++) // should be less than 2**(-30) of failure to find the right value
{
pair<int,int> cur = get_ans(dis(gen)%n);
max_side = max(max_side,cur.first+cur.second);
}
int left = 0;
int right = n-1;
while(true)
{
pair<int,int> cur = get_ans(left);
if(cur.first + cur.second == 0) return left;
if(cur.first + cur.second == max_side) break;
left++;
}
while(true)
{
pair<int,int> cur = get_ans(right);
if(cur.first + cur.second == 0) return right;
if(cur.first + cur.second == max_side) break;
right--;
}
//cout << left << " " << right << endl;
vector<pair<int,int>> I = {make_pair(left,right)};
while(true)
{
vector<pair<int,int>> new_I;
for(auto i:I)
{
int left = i.first;
int right = i.second;
// cout << left << " " << right << endl;
int lmid = int((left+right)/2);
int rmid = lmid + 1;
while(true)
{
pair<int,int> cur = get_ans(lmid);
if(cur.first + cur.second == 0) return lmid;
if(cur.first + cur.second == max_side) break;
lmid--;
}
while(true)
{
pair<int,int> cur = get_ans(rmid);
if(cur.first + cur.second == 0) return rmid;
if(cur.first + cur.second == max_side) break;
rmid++;
}
//cout << "LR: " << lmid << " " << rmid << endl;
if(get_ans(lmid).first > get_ans(left).first) new_I.push_back({left,lmid});
if(get_ans(right).first > get_ans(rmid).first) new_I.push_back({rmid,right});
}
I = new_I;
}
}
#ifdef ARTHUR_LOCAL
int main()
{
real_deal = {3,1,2,2,3,3,3,3};
cout << find_best(8) << endl;
}
#endif
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |