ABC
E - Random Swaps of Balls

E - Random Swaps of Balls

キーワード

解説

問題 (opens in a new tab)

まず、 i=0,1,,K, j=0,1,,N1i=0,1,\dots,K, ~ j=0,1,\dots,N-1 に対して、 dpi,jdp_{i,j} を次のように定める。

ii 回の操作の後、 j+1j+1 番目に黒いボールがある確率。

dp0,0=1, dp0,j=0(j=1,2,N1)dp_{0,0} = 1,~dp_{0,j} = 0 (j=1,2\dots,N-1) で初期化される。

ii 回目の操作の後、 jj 番目に黒いボールがあるのは、次の 2 通りのいずれかである。

  • i1i-1 回目の操作の後、 jj 番目に黒いボールがあり、 ii 回目の操作でそのボールが移動しなかった。
  • i1i-1 回目の操作の後、 l(j)l (\neq j) 番番目に黒いボールがあり、 ii 回目の操作で jj 番目のボールと ll 番目のボールが交換された。

それぞれの条件付き確率は、 (N1)2+1N2=N22N+2N2\frac{(N-1)^2 + 1}{N^2} = \frac{N^2-2N+2}{N^2}2N2\frac{2}{N^2} であるから、次のような漸化式が成り立つ。

dpi,j=(N22N+2N2)dpi1,j+lj2N2dpi1,l=(N22N+2N2)dpi1,j+2N2ljdpi1,l=(N22N+2N2)dpi1,j+2N2(1dpi1,j)=(N22NN2)dpi1,j+2N2=(N2N)dpi1,j+2N2\begin{align*} dp_{i,j} &= \left( \frac{N^2-2N+2}{N^2} \right) dp_{i-1,j} + \sum_{l \neq j}{\frac{2}{N^2} dp_{i-1,l}} \\ &= \left( \frac{N^2-2N+2}{N^2} \right) dp_{i-1,j} + \frac{2}{N^2}\sum_{l \neq j}{dp_{i-1,l}} \\ &= \left( \frac{N^2-2N+2}{N^2} \right) dp_{i-1,j} + \frac{2}{N^2}(1-dp_{i-1,j}) \\ &= \left( \frac{N^2-2N}{N^2} \right) dp_{i-1,j} + \frac{2}{N^2}\\ &= \left( \frac{N-2}{N} \right) dp_{i-1,j} + \frac{2}{N^2}\\ \end{align*}

ここで、 i=0,1,,Ki=0,1,\dots,K に対して、 EiE_i を次のように定める。

ii 回目の操作の後の黒いボールの位置の期待値。

すると、Ei=j=0N1(j+1)dpi,jE_i = \sum_{j=0}^{N-1}{(j+1)dp_{i,j}} であるから、

Ei=j=0N1(j+1)dpi,j=j=0N1(j+1)((N2N)dpi1,j+2N2)=(N2N)j=0N1(j+1)dpi1,j+2N2j=0N1(j+1)=(N2N)Ei1+2N2N(N+1)2=(N2N)Ei1+N+1N\begin{align*} E_i &= \sum_{j=0}^{N-1}{(j+1)dp_{i,j}} \\ &= \sum_{j=0}^{N-1}{(j+1)\left(\left( \frac{N-2}{N} \right) dp_{i-1,j} + \frac{2}{N^2}\right)} \\ &= \left( \frac{N-2}{N} \right) \sum_{j=0}^{N-1}{(j+1)dp_{i-1,j}} + \frac{2}{N^2} \sum_{j=0}^{N-1}{(j+1)} \\ &= \left( \frac{N-2}{N} \right) E_{i-1} + \frac{2}{N^2} \frac{N(N+1)}{2} \\ &= \left( \frac{N-2}{N} \right) E_{i-1} + \frac{N+1}{N} \\ \end{align*}

という漸化式が得られる。最初、黒いボールは 11 番目にあるから E0=1E_0 = 1 である。

これは、 O(K)\mathrm{O}(K) で計算可能。

提出コード

  • Go
const MOD = 998244353
 
func main() {
	var n, k int
	scanIntVariables(&n, &k)
	dp := make([]int, k+1)
	dp[0] = 1
	for i := 1; i <= k; i++ {
		dp[i] = (n-2)*modPow(n, MOD-2, MOD)%MOD*dp[i-1]%MOD + (n+1)*modPow(n, MOD-2, MOD)%MOD
		dp[i] %= MOD
	}
	writeLine(dp[k])
}
  • C++
const ll MOD = 998244353;
 
ll modPow(ll x, ll n, ll mod) {
    ll res = 1;
    while(n > 0) {
        if(n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}
 
int main() {
    ll n,k; cin >> n >> k;
    vector<ll> dp(k+1);
    dp[0] = 1;
    rep(i,1,k+1) {
        dp[i] = (n-2)*modPow(n, MOD-2, MOD)%MOD*dp[i-1]%MOD + (n+1)*modPow(n, MOD-2, MOD)%MOD;
		dp[i] %= MOD;
    }
    cout << dp[k] << endl;
}