データ構造

二分探索

整列済み配列の中央の値を調べ、対象があり得る側だけを残します。比較のたびに候補が半分になります。

lo・mid・hiと候補区間の縮小を表示する二分探索シミュレーター

対象値を変更するか、配列の値を選んで再生してください。薄くなったセルは候補から除外済みです。

時間計算量O(log n)
前提条件整列済み配列
100万個最大20回の比較
10億個最大30回の比較

二分探索の3つの形

値の検索は一致した位置で停止します。lower boundはx以上となる最初の位置、upper boundはxより大きい最初の位置を返します。両者の差はxの個数です。「重複が多い」で試してください。Pythonでは bisect_left(a, x)がlower bound、 bisect_right(a, x)がupper boundです。

区間の定義を統一する

この値の検索では閉区間[lo, hi]を使い、条件は lo <= hiです。lower/upper boundでは半開区間[lo, hi)を使い、条件は lo < hiです。定義を混ぜると無限ループや境界のずれが起こります。

パラメトリックサーチ:答えを二分探索する

実現可能な最大値・最小値を探すときは、候補xが実現可能かを判定する関数を用意します。xの増加に対し真偽が一度だけ切り替わるなら、その境界を二分探索できます。ケーブルの切断、木材の切断高さ、ルーターの配置などが例です。

lo, hi = 1, max(a)          # 答えの候補範囲
while lo <= hi:
    mid = (lo + hi) // 2
    if ok(mid):             # midは実現可能
        ans = mid
        lo = mid + 1        # さらに大きい答えを試す
    else:
        hi = mid - 1