整数二分的本质:
单调性的一定可以二分,但是二分的不一定有单调性,所以二分的本质不是单调性
二分的本质是边界,有一个边界,使得在右边区间不满足,左半边满足或相反
一共有两个常用的模板
1、
找第一个小于等于x的数
int l = 0 , r=n;
while(l<r){
int mid =l+r+1>>1;
if(q[mid]<=x) l=mid; //这种情况需要算mid时加上1,否则放l=r-1时,会出现死循环的情况。
else r=mid-1;
}
2、找第一个大于等于x的数
int l = 0 , r=n;
while(l<r){
int mid =l+r>>1;
if(q[mid]>=x) r=mid;
else l=mid+1;
}
yxc的模板
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
整数二分模板主要的差异还是在于mid计算是是否加1 的问题
实数二分
实数二分不会涉及到mid加一的问题,因为实数二分一般是给定一个精度进行的
一般给定精度为小数后6位的话,给1e-8的精度,以此类推
模板比较简单
while(r-l>=1e-8){
double mid =(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
对于求次方根的题,比如求0.01的二次方根,答案应该是0.1,所以取范围时一定要注意,应该取max(1,x);