方法一:普通二分
二分法处理时遇到的边界问题
搜寻第一个等于目标值的位置
int mid=l+r>>1; if(a[mid]>=L) r=mid; else l=mid+1;
寻找最后一个等于目标值的位置
int mid=l+r+1>>1; if(a[mid]<=L) l=mid; else r=mid-1;
为什么这样写?想想左右边界是3和4的时候目标值分别是3和4时该怎么处理
C++普通代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
int L;
while(cin>>L,m--)
{
int l=1,r=n,x;
while(l<r)
{
int mid=l+r>>1;
if(a[mid]>=L) r=mid;
else l=mid+1;
}
if(a[l]!=L)
{
cout<<"-1"<<" "<<"-1"<<endl;
continue;
}
x=l;
l=1,r=n;
while(l<r)
{
int mid=l+r+1>>1;
if(a[mid]<=L) l=mid;
else r=mid-1;
}
cout<<x-1<<" "<<r-1<<endl;
}
return 0;
}
方法二:使用c++函数
lower_bound用于寻找第一个大于或目标值的位置
upper_bound用于寻找第一个大于目标值的位置(两个函数是基于二分实现的)
所以当两个函数的返回值相同时,没有搜索到目标值
C++代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int>a;
int main()
{
int n,m,x,L;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>x,a.push_back(x) ;
while(cin>>L,m--)
{
auto l=lower_bound(a.begin(),a.end(),L);
auto r=upper_bound(a.begin(),a.end(),L);
if(l==r) cout<<"-1 -1"<<endl;
else cout<<l-a.begin()<<" "<<r-a.begin()-1<<endl;
}
return 0;
}