//二分,二分之前一定要排序,
//二分查找符合条件的一个范围的的一个边界值
//还是二分舒服,一遍过
#include<cstdio>
using namespace std;
const int N=100005;
int a[N];
int main(){
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int k;
for(int i=1;i<=q;i++){
scanf("%d",&k);
int l=1,r=n,mid;
while(l<r){//之间还有数
mid=l+r >> 1;
//找左边界
//找的是满足>=k的序列的最小的值,就是左端
if(a[mid]>=k){ //为什么写>=k 因为=k的时候要找一个最小值
r=mid;
}else{
l=mid+1;
}
}
// l==r
if(a[l]!=k){
printf("-1 -1\n");
continue;
}
printf("%d ",l-1);
//找右边界
l=1,r=n;
while(l<r){
mid= l + r + 1 >> 1;
if(a[mid]<=k){
l=mid;
}else{
r=mid-1;
}
}
printf("%d\n",l-1);
}
return 0;
}
模板如下,有两个:
强调:
有单调性,一定可以二分.
没有单调性,也有可能二分.