整数二分

整数二分

重新开始写一遍二分吧。其实看起来很简单,但是写的时候细节确实很多,不小心就会写错。

功利一点,先从板子开始吧。

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 都要保证这一点
  • 第一次改变 lr,接在条件为真的时候,左右端点均保持原样即可
  • 第二次改变 lr,和步骤二相反:
    • 如果是 l ,则不变
    • 如果是 r ,则必须 -1
  • 最后总是返回左端点 l

参考博客:

常用代码模板1——基础算法 - AcWing

AcWing 789. 二分模板笔记 - AcWing

posted @ 2021-09-28 19:34  Salty_Fish  阅读(43)  评论(0编辑  收藏  举报