- 二分的最基本条件是,我们二分的序列需要有单调性,这里的序列是广义性如:
- 1.一个排好序的数组; 2.一个区间[L,R),所以下面二分的目标一般有四种ans表示查询的目标:
- 1第一个大于ans的值。2第一个大于等于ans。3最后一个小于ans。4最后一个小于等于ans。
-
1.第一个大于等于ans
- 这就是我们常说的lower_bound()了,这是系统里面自带的库函数,在数组或者一个vector容器中二分的时候,也就是不是必须手写二分的时候首推使用这个。这里我们来介绍lower_bound()的使用方式。
- 函数原型:ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,const T& val, Compare comp)
- 其中first代表左边界迭代器,last代表右边界迭代器(注意左闭右开),val代表你要搜索的值,comp代表排序规则
- (这个参数在你对非结构体数组二分的时候并不需要,有默认规则)
- vector + cmp 使用方法 :index=lower_bound(a.begin(),a.end(),b,cmp)-a.begin();
- 普通数组 :p=lower_bound(a,a+len,n)-a;
-
2.第一个大于ans
- 这就是我们常说的upper_bound()了,这是系统里面自带的库函数,这里我们来介绍upper_bound()的使用方式,和lower_bound()在可以使用的时候推荐使用。
- 函数原型:ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,const T& val, Compare comp);
- 其中first代表左边界迭代器,last代表右边界迭代器(注意左闭右开),val代表你要搜索的值.
- comp代表排序规则(这个参数在你对非结构体数组二分的时候并不需要,有默认规则)
-
#include<bits/stdc++.h> using namespace std; int a[15]= {1,1,1,2,2,3,3,3,3,4,5,6},p; int main() { p=lower_bound(a,a+12,3)-a; //p=5,第一个>=ans的位置 cout<<p<<endl; p=upper_bound(a,a+12,3)-a; cout<<p<<endl; //p=9,第一个>ans的位置 return 0; }
-
3.最后一个小于等于v
-
4.最后一个小于v
-
#include<bits/stdc++.h> using namespace std; int a[15]= {1,1,2,2,3,3,3,4,5,6,6},p; int main() { int l=-1,r=10,ans; cin>>ans; //最后一个小于等于ans的位置 while(l<r) { int m=(l+r+1)/2; if(a[m]<=ans)l=m; else r=m-1; } cout<<l<<endl; l=-1,r=10; //最后一个小于ans的位置 while(l<r) { int m=(l+r+1)/2; if(a[m]<ans)l=m; else r=m-1; } cout<<l<<endl; return 0; }
二分搜索详细简单总结
最新推荐文章于 2023-11-04 19:47:10 发布