二分总结
二分是一种高校的查找数据方式,每次查找的时间复杂度为\(O(logn)\)
不过前提条件是所查找的数据具有单调性
二分
二分具有两种类型
二分查找
顾名思义,通过二分查找所找需数据
基础题型
inline int find(int x){
int l=1,r=n;
while(l<=r){
int mid=(l+r)>>1;
if(a[mid]>=x) r=mid-1;//第一次出现的位置,如果有多个,查到相同的就可以继续缩小有边界
else l=mid+1;
}
if(a[l]==x) return l;
return -1;
二分答案
二分答案的使用建立在答案具有单调性的性质之上
- 什么是答案有单调性?
从牛客小白月赛104之后又有新的认识,我们所寻找的答案,从某个合法答案开始,增加了仍然可以合法,但减少了就不合法,而二分答案一般是寻找最合适的那个答案
我的解释可能不太懂,但是二分答案题做多了,自然就能理解了 - 二分答案题的一种特征:
我们通过纯粹的模拟或者暴力,难以得到一个好的程序得出答案,或者说找到答案的过程比较难以设计
但是如果我们预先知道答案,那么检验答案的正确性的程序会更加容易
1.简单检验答案
-
整数
P1873 [COCI 2011/2012 #5] EKO / 砍树
每个树的高度\(tree[i]\),得到的木材是所有数高于H的树的部分即\(ans=sum_{i=1}^{n}(tree[i]-H)\)
ans随H的增高具有单调递减性
-
实数
AcWing5048. 无线网络
二分半径即可,注意精度即可while((rx-lx)>1e-7){//这样处理可以满足精度要求
2.二分+前缀和
AcWing 102. 最佳牛围栏
其实二分答案难的不是二分,难得是怎么check
在给定条件下,计算围起区域内每块地包含的牛的数量的平均值可能的最大值是多少。
显而易见二分平均值,寻找是否存在一个区间满足二分平均值,满足则提高枚举左边界,否则降低平均值
做法:双指针+前缀和,左指针找最小值,寻找是否存在这样一个区间
3.二分+最短路
在所有可以到达奥格瑞玛的道路中,对于每条道路所经过的城市收费的最大值的最小值为多少(经典二分设问方式)
这一句话就是题关键
- 收费是单调的
- 检验方式:就是是否可达(根据题目要求写最短路就行,防止血量不够死去
二分线路花费
check角度就是寻找是否存在k条的线路小于二分的花费,小于k的边贡献为1,否则为0,用dijkstra找到最短路检验即可
\(\\\)
此时可以用双端队列代替堆,+1入队尾,+0入队首,保证单调性,降低时间复杂度
(PS:此题还可以用分层图)