根据百度百科信息,二分法的算法:二分法查找适用于数据量较大时,但是数据需要先排好顺序。或者说,有一个临界值,临界值之前满足条件,超过临界值之后不满足条件。
一般来说,二分法的时间复杂度为O(logN),比一般遍历O(N)要优秀。日常生活中,在一串(有序的)数据中,要找到一个特定对象,也可以使用二分法来查找来使操作难度降低,最简单的例子就是翻字典。
我二分法的引入是砍树问题(洛谷p1873)
n棵树高度分别为a1,a2,...,an,对于一个砍树高度h,可以锯下并收集到每棵树比h高的部分的木料,现在需要求高度h使得能够收集到长度为m的木材。其中n<=10e6,树高不超过10e9。例如,有5棵树,需要收集到20单位的木材,每棵树的高度分别是【4,42,40,26,46】,需要将锯子的高度调整为36,这样可以分别锯下【6,4,10】高度的木材。如果锯子高度再高一点就不能满足要求了。
二分模板如下:
bool check(long long x) { //判断条件; } long long l=0,r=1e18,ans; while(l<=r) { long long mid=(l+r)>>1;//X>>1=X/2 if(check(mid)){ ans=mid; r=mid-1; } else l=mid+1; }
最简单的二分如下(相当于lower_bound,upper_bound需要加#include<bits/stdc++.h>头文件 using namespace std命名空间清零):
#include<stdio.h> int low = 0; int high = 100000; int mid = 0; int n; bool check(int mid){ return mid>n; } int main(){ scanf("%d",&n); while(low<=high){ mid = (low + high)/2; if(mid == n){ printf("%d",mid); } if(check(mid)){ high = mid - 1; } else if(!check(mid)){ low = mid + 1; } } return 0; }