PrepStack · Markdown HTML

二分边界 / First True

二分与单调答案 · HTML

数学 / 逻辑形态

维护闭区间 [lo,hi] 且已知答案存在其中;mid 为 True 时保留 mid 并令 hi=mid,否则排除 mid 令 lo=mid+1,终止于 lo=hi。

识别信号

容易误判的相似信号

SignalWhy it is different
任意精确命中不要求边界时普通二分更直观。
非单调谓词T/F 多次交替时,丢掉一半没有逻辑依据。

核心不变量

第一个 True 始终位于 [lo,hi];hi 一侧是保留的可行候选,lo 左侧已证为 False。

状态、转移与处理顺序

ItemDefinition
Statelo、hi、mid 和单调 predicate;模板假设区间内至少一个 True。
Transitionpredicate(mid) 为 True:hi=mid;否则 lo=mid+1。
Frontier / order仍可能成为转折点的闭区间;mid 为 True 时不能做 hi=mid-1,因为 mid 可能就是答案。

Python 骨架

def first_true(lo, hi, predicate):
    # Precondition: predicate(hi) is True.
    while lo < hi:
        mid = lo + (hi - lo) // 2
        if predicate(mid):
            hi = mid
        else:
            lo = mid + 1
    return lo

正确性思路

  1. 若 predicate(mid) 真,单调性只说明答案不在 mid 右边,mid 本身仍可能是首真,故保留 [lo,mid]。
  2. 若为假,mid 及左侧都不可能是首真,安全保留 [mid+1,hi]。
  3. 区间严格缩小到单点;不变量与存在性保证该点就是首真。

复杂度

TimeSpaceParameters
O(log N) 次谓词调用O(1) 外加谓词空间N=hi-lo+1;若 predicate 成本为 C,总时间 O(C log N)。

边界条件

错误模式

PatternWhy it fails / fix
True 时 hi=mid-1会丢掉可能的第一个 True。
while lo<=hi 混搭 hi=mid区间语义不一致,容易死循环。
未验证单调性局部样例看似可用,不代表谓词只有一次转折。

选择与排除规则

相关模板

RelationTemplateBoundary
控制结构母版答案空间二分can(x) 就是 first-True 谓词。
加速谓词前缀和 / 区间聚合边界判断需频繁查询区间聚合。
组合查询Sparse Table 静态 RMQ用 O(1) RMQ 检验并寻找边界
optimization子序列 DP某些单序列递增子序列长度可用 tails + lower_bound。

原创微型例子

环节内容
Result收敛到首个 True 的索引 3。
Setup谓词在索引 0..6 上为 F,F,F,T,T,T,T。
Trace检查 3 得 T,保留 [0,3];检查 1 得 F,保留 [2,3];检查 2 得 F。

Recall prompts

我的补充