原题链接:
https://www.acwing.com/problem/content/791/https://www.acwing.com/problem/content/791/二分的思想很简单
就是不断的更新满足条件的数组的边界,来达到查找满足条件的数组的下标范围
对于本题来说就是找寻询问数字的下标范围
这里我们先找左边界
int l=0,r=n-1;
while(l<r)
{
int mid=l+r >> 1;
if(a[mid]>=k) r=mid;
else l=mid +1;
}
从整段的区间开始查找
当mid值大于等于k值时,则满足条件的数就在[l,mid]之间,更新右端点为mid;
反之则满足条件的数在[mid+1,r]之间,则更新左端点为mid+1;
循环到最后找到的l和r肯定是相等的,并且l下标对应的是第一个满足条件的数的下标;
输出l即为左端点;
注意:此处需特判不存在的情况,即判断一下l或r下标所对应的数与k是否相等即可
右端点同理
放出全代码
#include <bits/stdc++.h>
using namespace std;
const int N =1e5+10;
int n,q;
int a[N];
int main ()
{
cin >> n >> q;
for(int i=0;i<n;i++){
cin >> a[i];
}
while(q--){
int k;cin >> k;
int l=0,r=n-1;
while(l<r)
{
int mid=l+r >> 1;
if(a[mid]>=k) r=mid;
else l=mid +1;
}
if(a[l]!=k) cout << "-1 -1" << endl;
else {
cout << l << " ";
l=0,r=n-1;
while(l<r)
{
int mid=l+r+1 >> 1;
if(a[mid] <=k) l=mid;
else r=mid-1;
}
cout << l << endl;
}
}
return 0;
}