整数二分
整数二分
重新开始写一遍二分吧。其实看起来很简单,但是写的时候细节确实很多,不小心就会写错。
功利一点,先从板子开始吧。
bool check(int x)
{ /* ... */
} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
while (l < r) {
int mid = l + r >> 1;
if (check(mid))
r = mid; // check()判断mid是否满足性质
else
l = mid + 1;
}
return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
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;
}
主体真的很简单,整个流程:
while
循环- 取
l , r
中间值,那怎么判断是否需要+1
呢:- 观察下面的
if
- 如果是
l
,则+1
- 如果是
r
,则无需+1
- 如果是
- 为了方便记忆,可以认为左边的小,需要补个 1,右边较大所以不需要。
- 观察下面的
- 检查是否满足某个性质
- 如果满足该性质,则该点必须被包括在下次处理中
- 如果不满足该性质,则该点必须不包括在下次处理中
- 切记无论其后跟着的是
l
还是r
都要保证这一点
- 第一次改变
l
或r
,接在条件为真的时候,左右端点均保持原样即可 - 第二次改变
l
或r
,和步骤二相反:- 如果是
l
,则不变 - 如果是
r
,则必须-1
- 如果是
- 最后总是返回左端点
l
参考博客: