题解:P8122 [BalticOI 2021] A Difficulty Choice (Day1)
Xueqiaorui47 · · 题解
大便交互题
题意
给定一个长度为
数据范围:
题解
因为
分类讨论,按是否选了大于
如果你选了大于 check 最小的
第二种情况,你没有选大于
总共询问次数
完整代码
都写这么 shit 了还抄?
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
extern "C" ll skim(int i);
extern "C" void answer(std::vector<int> v);
extern "C" void impossible();
extern "C" void solve(int N, int K, ll A, int S)
{
int n=N;
ll a=A;
vector<ll>memory(N+1,-1);
auto ask=[&](int i)
{
if(memory[i]!=-1)return memory[i];
return memory[i]=skim(i);
};
deque<int>q;
ll sum=0;
for(int i=1;i<=K;++i)
{
sum+=ask(i);
q.emplace_back(i);
}
if(sum>a<<1)
{
impossible();
return;
}
if(sum>=a)
{
vector<int>out;
for(int i:q)out.emplace_back(i);
answer(out);
return;
}
auto get=[&]()
{
int l=K+1,r=n;
int ans=K;
while(l<=r)
{
int mid=(l+r)>>1;
if(ask(mid)<=A)ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
};
int rptr=get();
int lptr=K;
if(rptr!=n)
{
ll nsum=sum-ask(lptr)+ask(rptr+1);
if(a<=nsum&&nsum<=a<<1)
{
q.back()=rptr+1;
vector<int>out;
for(int i:q)out.emplace_back(i);
answer(out);
return;
}
}
int cnt=0;
while(sum<a&&cnt++<K&&K<rptr)
{
auto idx=q.front();
q.pop_front();
sum-=ask(idx);
sum+=ask(rptr);
q.emplace_back(rptr);
if(sum>=a)
{
vector<int>out;
for(int i:q)out.emplace_back(i);
answer(out);
return;
}
--rptr;
}
impossible();
}