解题思路
对于一个存在答案的区间 [ l , r ] [l,r] [l,r],我们考虑缩小答案所在区间范围,我们找到最大的i使得 2 i < = n 2^i<=n 2i<=n,若 a a n s + 2 i < q a_{ans+2^i}<q aans+2i<q,那么答案一定在子区间 [ a n s + 2 i + 1 , R ] [ans+2^i+1,R] [ans+2i+1,R]中,则 a n s = z + 2 i ans=z+2^i ans=z+2i,否则答案在子区间 [ a n s + 1 , a n s + 2 i ] [ans+1,ans+2^i] [ans+1,ans+2i]中,无需修改ans指针。当枚举结束时,若 a a n s + 1 = q a_ans+1=q aans+1=q,那么答案就是 a n s + 1 ans+1 ans+1,否则无解(第一个大于等于 q q q的数不是 q q q)
代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int n,m,x,a[1000010];
int find(int x){
int ans=0;
for(int i=20;i>=0;i--)
{
if(ans+(1<<i)<=n)
{
if(a[ans+(1<<i)]<x)
ans+=(1<<i);
}
}
if(a[ans+1]!=x)
return -1;
return ans+1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
printf("%d ",find(x));
}
}