学习笔记-3-二分
二分查找
具体思路为每次查找时,将范围折半,判断查找数的位置并将其折半,重复以上操作就可快速得出答案。注意操作时必须保证数组是有序的!!
时间复杂度
二分的最坏复杂度为 $O(log N)$
实现
手写
模板1
//往左找答案
while(l<r){
int mid=l+r>>1;//(l+r)/2
if(check(mid)){
r=mid;
}
else{
l=mid+1;
}
}
模板2
//往右找答案
while(l<r){
int mid=l+r+1>>1;//(l+r+1)/2
if(check(mid)){
l=mid;
}
else{
r=mid-1;
}
}
模板3(浮点)
while(r-l<1e-5){//注意所有类型都为double
double mid=(l+r)/2;
if(check(mid)){
l=mid;
}
else{
r=mid;
}
}
STL函数
查找首个不小于给定值的元素:lower_bound:
使用时直接调用lower_bound( ForwardIt first, ForwardIt last, const T& value );,使用时必须保证数组有序。
如果没有找到,返回last
查找首个大于给定值的元素: upper_bound:
使用时直接调用upper_bound( ForwardIt first, ForwardIt last, const T& value );,使用时必须保证数组有序。
如果没有找到,返回last
例题
P1163//浮点二分
二分答案
在题目的答案有一个很大的区间,且保证这个区间对题目中的某一个量具有单调性,就可以使用二分答案来解决问题。
形式化的来说,一道题目如果符合以下条件就可以使用二分答案来求解。
- 答案在一个区间。
- 直接搜索不容易,但是可以容易判断一个答案是否符合条件。
- 这个区间具有单调性,会随着一个条件的改变而变化。
- 可能会有最大值最小化(或者最小值最大化),等典型特征。
- check()函数要写正确,一般可以用答案带进去试。
- 注意一些特殊的情况,写好特判。
例题
本文采用 CC BY-NC 4.0 许可协议,转载请注明出处并保持非商业用途。