Skip to content →

二分探索


\(f : \mathbb{N} \to \mathrm{Bool}\) なる関数について、\(f(L) \neq f(R)\) ならば、

  • \(f(R)=f(r)\)
  • \(f(L)=f(l)\)
  • \(r=l+1\)
  • \(L \leq l \leq r \leq R\)

となる \(l, r\) のペアが一つ以上存在し、ある一つが次のアルゴリズムで必ず取れる。計算量は \(O(\log(n))\)。

l = L
r = R
while (r - l > 1):
    m = (r + l) // 2
    if f(m) == f(L):
        l = m
    else:
        r = m

特に、インタラクティブ問題で鍵になることが多い。
長さ2N(Nは奇数)の+1/-1の列aが与えられる。+1/-1はN個ずつある。f(l) は区間 [l,l+N) の和が負なら True, 正ならば False を返す。[l, l+N-1)の和が0, a[l] != a[r] となるような l を求めよ。

a[0..i)の値の種類数をO(1)で得られる。a[0]以外が分かっている。a[0]と等しい箇所が他に必ず存在する。a[0]を特定せよ。


\(f : \mathbb{N} \to \mathrm{Bool}\) なる関数について、\(f(L) \neq f(R)\) ならば、

  • \(f(R)=f(r)\)
  • \(f(L)=f(l)\)
  • \(r=l+1\)
  • \(L \leq l \leq r \leq R\)

となる \(l, r\) のペアが一つ以上存在し、ある一つが次のアルゴリズムで必ず取れる。計算量は \(O(\log(n))\)。

l = L
r = R
while (r - l > 1):
    m = (r + l) // 2
    if f(m) == f(L):
        l = m
    else:
        r = m

特に、インタラクティブ問題で鍵になることが多い。

  • 長さ2N(Nは奇数)の+1/-1の列aが与えられる。+1/-1はN個ずつある。f(l) は区間 [l,l+N) の和が負なら True, 正ならば False を返す。[l, l+N-1)の和が0, a[l] \neq a[r] となるような l を求めよ(ddcc2020_qual_e)。
  • a[0..i)の値の種類数をO(1)で得られる。a[0]以外が分かっている。a[0]と等しい箇所が他に必ず存在する。a[0]を特定せよ。

\(f\) を \(\mathrm{Bool}\) への関数ではなく \(\mathbb{Z}/\mathbb{2Z}\) への関数だと思うと \(f(R) \neq f(L)\) は
\begin{align}
&f(L) \neq f(R) \bmod 2 \\
\Leftrightarrow &f(R) \pm f(L) = 1 \bmod 2
\end{align}
となる。例えば、\(f(i)=g(i)+i\) とすると、\(g(R)-g(L)+(R-L) = 1 \bmod 2\)となるがこれは次のような問題に使える。

  • \(L, R\) に座っている2人が異性かつ \(L-R\) が偶数
  • \(L, R\) に座っている2人が同性かつ \(L-R\) が奇数

のとき、区間 \([L, R)\) に空席があることが分かっている。空席を一つ見つけよ。長さ奇数の円環上に椅子が並んでいるときに空席を一つ見つけよ(APC001C)

判定問題にすることで実装の簡略化

もっと良い計算量で解けるのに、あえて二分探索で判定問題に帰着し、実装を簡略化するテクニックがある。

2 × n のマスがある。各マス \((i, j)\) には時刻 \(a_{i, j}\) 以降でないと入れない。隣接するマスには時間 1 を掛けて移動できる。\((1, 1)\) を始点とするハミルトンパスを作るのに必要な時間を求めよ。(ECF133C)

Published in データ構造

Comments

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA