443 字
2 分钟
学习笔记-3-二分
二分查找
具体思路为每次查找时,将范围折半,判断查找数的位置并将其折半,重复以上操作就可快速得出答案。注意操作时必须保证数组是有序的!!
时间复杂度
二分的最坏复杂度为
实现
手写
模板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()函数要写正确,一般可以用答案带进去试。
- 注意一些特殊的情况,写好特判。