二分

\[\texttt{Although\ the\ basic\ idea\ of\ binary\ search\ is\ comparatively\ straightforward,} \]

\[\texttt{the\ details\ can\ be\ surprisingly\ tricky.} \]

\[\tag*{\color{black}\text{——Donald Ervin Knuth}} \]

\[\color{white}6 \]

二分

该算法在数学中也有广泛的应用,在数学中,我们求函数零点时也会采取这种方式。

该算法思路非常简单:就是在知道答案的范围时,对答案进行夹逼,直到夹逼出一个固定值或者精度满足要求的数字为止。

大致过程

  1. 已知答案在 \([l,r]\) 的范围内;
  2. 每次取 \(mid=\frac{l+r} 2\)
  3. \(mid\) 进行判定,判断 \(mid\) 是否满足条件;
  4. 如果 \(mid\) 满足条件,缩小区间为 \([mid,r]\),否则缩小区间为 \([l,mid]\)
  5. 回到 2 操作继续进行,直到找到答案或精度足够为止。

要求

  • 在进行整数二分时,对于所二分的条件 check,长度为 \(n\) 的数组 \(a\) 中恰有一点 \(i\),使得 \([1,i]\) 都满足 check 函数,使得 \([i+1,n]\) 都不满足 check 函数。
  • 小数二分求函数零点时,必须保证在所求范围内,函数需要满足确定的单调性。

时间复杂度

时间复杂度是一个典型的 \(O(\log n)\),常数也很小,效率非常高。

整数二分

适用情况

整数二分通常用于下列情况:求大于(等于)或小于(等于)一个数字的第一个(最后一个)数字、求整数答案、求整数(自然数)最优解,求第一个满足条件的情况或数字。

实现细节

整数二分时,我们的退出条件应为 \(l>r\)\(l\geq r\),会因写法而异,而缩小区间时,我们需要使得 \(l:=mid+1\)\(l:=mid\)\(r:=mid-1\)\(r:=mid\),同样也因写法而异,如果没有选择合理的组合,二分就有可能死循环或者挂掉,而且最终是输出 \(l\) 还是 \(r\)\(l+1\) 还是 \(r-1\)\(l-1\) 还是 \(r+1\),都需要我们费脑子去想,如果没想对就会出错。
正如开头所说,二分的过程中细节非常多的,写错一点可能就很难调出,即使能够对于样例输出正确的答案,二分算法也不一定正确,我们需要找到一种稳定的方式,较为简单地实现整数二分。

在实践中,如果添加一个变量 \(res\) 来记录答案,就可以规避掉这个问题,具体写法如下:

int l,r,res=-1; // 将 l 和 r 设为二分范围
while(l<=r) {
    int mid=l+r>>1;
    if(check(mid)) res=mid,l=mid+1; // 根据所需选择 l=mid+1 还是 r=mid-1
    else r=mid-1; // 同理,根据所需选择 l=mid+1 还是 r=mid-1
}
if(res==-1) ; // No Answer 
else ; // 答案即为 res

这样,变量 \(res\) 记录的值就是我们的答案,规避掉了考虑输出 \(l\) 还是 \(r\) 的问题,所以,这种写法应该是整数二分中最为稳妥的。

小数二分

适用情况

小数二分通常用于下列情况:求函数零点、方程的解、求平均值或欧几里得距离等可能出现小数的答案。

实现

小数二分时,我们的退出条件应为 \(r-l<eps\),其中 \(eps\) 表示需要的精度,因题目要求而异,而缩小区间时,按需使 \(l:=mid\)\(r:=mid\)

不过,只要精度足够,输出 \(l\) 还是 \(r\) 其实都无伤大雅,所以,小数二分相对于整数二分而言就没有那么多烦人的细节,也没有太多多变的写法。

const double eps; // eps 表示所需精度
double l,r; // l 和 r 是二分区间
while(r-l>eps) {
    double mid=(l+r)/2.;
    if(check(mid)) l=mid; // 根据所需选择 l=mid 还是 r=mid
    else r=mid; // 同理,根据所需选择 l=mid 还是 r=mid
}
// 此时,答案就是 l 或者 r 了,具体取哪个都无所谓

洛谷练习题单:https://www.luogu.com.cn/training/111#problems

posted @ 2023-04-28 19:12  abensyl  阅读(35)  评论(0)    收藏  举报  来源
//雪花飘落效果