AtCoder: エクサウィザーズ2019 - E問題: Black or White
コンテスト中に解けなかった問題。思考力が足りなかった (終)
想定解法メモ。
問題概要
個の黒いチョコレートと個の白いチョコレートがある。
黒と白を等確率で選び、選んだ色のチョコレートが存在すれば食べる、をチョコレートがなくなるまで繰り返す。
各 について、番目に食べるチョコレートが黒である確率をmod で求めよ。
制約
解法
うまく確率を計算する。
まず、番目までどのような選び方をしても黒と白のチョコレートがそれぞれ1枚以上残る場合、番目の答えはになる。
問題は、片方がなくなりうる場合()の確率である。
黒を枚、白を枚食べたことをと表すとき、確率がでなくなるのは、以下の場合である。
- の時: 次は必ず白を食べる -> 確率は0
- の時: 次は必ず黒を食べる -> 確率は1
よって、番目で黒を選ぶ確率は、
- (i番目でどちらも選べる確率) × + (i番目で黒しか選べない確率) × 1
が計算できればよいことが分かる。
ここで、に到達する確率を、に到達する確率をとする。
これが計算できれば、番目の解は
(i番目でどちらも選べる確率) × + (i番目で黒しか選べない確率) × 1 =
と求められる。
このは、以下のように計算できる。
階乗とその逆数を前もって計算することで、計算量は になる。
実装
提出コード(Python3): Submission #4787508 - ExaWizards 2019
import sys write = sys.stdout.write B, W = map(int, sys.stdin.readline().split()) MOD = 10**9 + 7 # 前計算 L = B+W fact = [1]*(L+1) rfact = [1]*(L+1) for i in range(L): fact[i+1] = r = fact[i] * (i+1) % MOD rfact[L] = pow(fact[L], MOD-2, MOD) for i in range(L, 0, -1): rfact[i-1] = rfact[i] * i % MOD rev2 = pow(2, MOD-2, MOD) # 各iについて計算していく p = q = 0 L = min(B, W) r2 = "%d\n" % rev2 for i in range(L): write(r2) base = pow(rev2, L-1, MOD) rB = rfact[B-1]; rW = rfact[W-1] for i in range(L, B+W): base = rev2 * base % MOD if i >= B: p = (p + (fact[i-1]*rfact[i-B] % MOD) * (rB * base % MOD) % MOD) % MOD if i >= W: q = (q + (fact[i-1]*rfact[i-W] % MOD) * (rW * base % MOD) % MOD) % MOD write("%d\n" % ((1-p+q)*rev2 % MOD))