题目链接:https://www.luogu.com.cn/problem/P5208
有一个长度为n的01序列a,你知道里面有奇数个1还是偶数个1。你每次可以选择两个下标集合S/T询问集合S和集合T位置的数字和哪个更大。
交互库只会告诉你S≤T或者S≥T。
要求在所有询问集合大小之和不超过 500100 的情况下得到整个a序列。
1≤n≤105
注意到数据中有一个点保证了a序列单调,我们先假设为单调不升。
此时有a1=1,那么我们考虑二分,对于一个位置mid,我们判是否amid+amid+1≤1,如果是,那么说明amid+1=0,否则amid+amid+1≥1就说明了amid=1。
这样我们同样每次能过缩小一半,但是最后会剩下两个数字,我们用奇偶性去判断。
那么对于一般的情况,我们考虑也去构造一个单调不升的序列,两个数字比不出东西,我们考虑拿三个数字去比较,假设我们现在有一个a≤b。
我们拿a+b和c去比较:
- 若a+b≤c,那么有a=0。
- 若a+b≥c,那么有b≥c,我们把b加入队列,这样加入队列的都是单调不升的。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int p[N],A[2],B[2];
int query(int *S,int nS,int *T,int nT);
void find_price(int task_id, int n, int k, int ans[]) {
if(n==1){ans[0]=1;return;}
if(task_id==3||n==2){
A[0]=0;B[0]=n-1;
if(!query(A,1,B,1))
for(int i=1;i<=n;i++)p[i]=i-1;
else
for(int i=1;i<=n;i++)p[i]=n-i;
int l=1,r=n-1;
while(l<r){
int mid=(l+r+1)>>1;
A[0]=p[mid];A[1]=p[mid+1];B[0]=p[1];
if(query(A,2,B,1))
r=mid-1;
else l=mid;
}
ans[p[l+1]]=(l&1)^k;
for(int i=1;i<=l;i++)ans[p[i]]=1;
}
else{
int x=0,y=1,tot=0;
for(int i=2;i<n;i++){
int z=i;A[0]=y;B[0]=z;
if(query(A,1,B,1))swap(y,z);
A[0]=x;B[0]=y;B[1]=z;
if(query(A,1,B,2)){
p[++tot]=x;
x=y;y=z;
}
else ans[z]=0;
}
A[0]=x;B[0]=y;
if(query(A,1,B,1))p[++tot]=y;
else p[++tot]=x,swap(x,y);
for(int i=1;i<tot-i+1;i++)swap(p[i],p[tot-i+1]);
int l=1,r=tot-1;
while(l<r){
int mid=(l+r+1)>>1;
A[0]=p[mid];A[1]=p[mid+1];B[0]=p[1];
if(query(A,2,B,1))
r=mid-1;
else l=mid;
}
for(int i=1;i<=l;i++)ans[p[i]]=1;
y=p[l+1];A[0]=x;B[0]=y;
if(query(A,1,B,1))swap(x,y);
A[0]=x;A[1]=y;B[0]=p[1];
if(query(A,2,B,1))ans[y]=0;
else ans[x]=1,l++,x=y;
ans[x]=(l&1)^k;
}
return;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2021-07-11 P7717-「EZEC-10」序列【Trie】