エクサウィザーズ 2019 E Black or White
エクサウィザーズ 2019 E Black or White の解説。
コンテスト中に解けたのが嬉しかったので、ついでに解説を書く。
問題はこれ
E - Black or White。
解説はこれ
https://img.atcoder.jp/exawizards2019/editorial.pdf。
解説
まず、 回目までに 個の黒が全て出る確率 を求める。
これは、 回目で最後の黒が出る確率の和になる。
回目に、最後の黒が出る場合の数は、 回目までに黒がちょうど 回出る数に等しい。
つまり、 になる。
また、 回目までで黒が全て出ることはない。
まとめると、
となります。
同様に、 回目までに 個の白が全て出る確率 は、
で与えられます。
では、 回目に黒が出る確率を求めます。
これは、 回目の操作を行う前に黒と白がそれぞれ少なくとも1つあれば、
になります。
(回目の操作の後、白と黒が少なくとも1つある確率)
は、 回目の操作の後、黒または、白が出尽くしているわけではないと言い換えられるので、
となります。
白または、黒しか無い場合は黒しか見る必要がないので、
となります。これは、回目までに白が全部出ていれば、残りは黒しか出ないためです。
というわけで、 回目に黒が出る確率は、
となります。
後は、頑張って実装します。
解答
Q = 10**9+7 def getInv(N):#Qはmod inv = [0] * (N + 1) inv[0] = 1 inv[1] = 1 for i in range(2, N + 1): inv[i] = (-(Q // i) * inv[Q%i]) % Q return inv B, W = map( int, input().split()) Z = getInv(B+W) I = [1]*(B+W+1) for i in range(1,B+W+1): I[i] = (I[i-1]*Z[i])%Q F = [1]*(B+W+1) for i in range(1,B+W+1): F[i] = F[i-1]*i%Q w = 0 b = 0 for i in range(1,B+W+1): if i - 1 < B and i - 1 < W: print(I[2]) elif i - 1 >= W and i - 1< B: #i > B w += F[i-2]*I[i-1-W]%Q*I[W-1]%Q*pow(I[2],i-1,Q)%Q w %= Q print(((1 - w)%Q*I[2]%Q + w)%Q) elif i - 1 >= B and i - 1 < W: #i > W b += F[i-2]*I[i-1-B]%Q*I[B-1]%Q*pow(I[2],i-1,Q)%Q b %= Q print((1-b)%Q*I[2]%Q) else: w += F[i-2]*I[i-1-W]%Q*I[W-1]%Q*pow(I[2],i-1,Q)%Q w %= Q b += F[i-2]*I[i-1-B]%Q*I[B-1]%Q*pow(I[2],i-1,Q)%Q b %= Q print(((1 - w - b)%Q*I[2]%Q + w)%Q)
おまけ
mod の逆元を求める記事書いたと思ったけど、書いてなかった。