1. 程式人生 > 實用技巧 >Solution -「CF 1392H」ZS Shuffles Cards

Solution -「CF 1392H」ZS Shuffles Cards

\(\mathcal{Description}\)

  Link.

  打亂的 \(n\) 張編號 \(1\sim n\) 的數字排和 \(m\) 張鬼牌。隨機抽牌,若抽到數字,將數字加入集合 \(S\);否則,還原牌堆(但不清空 \(S\))。若 \(S=[1,n]\) 且抽到鬼牌時結束抽牌。求期望抽牌次數。

  \(n,m\le2\times10^6\)

\(\mathcal{Solution}\)

  稱從初始牌堆開始抽牌一直到抽到鬼牌為一輪操作,發現結束時必然抽了若干個完整的輪且不能中途終止。所以“抽完一輪”和“結束抽牌”兩事件獨立,分別記二者的隨機變數為 \(\xi_1\)\(\xi_2\)

,則答案為 \(E(\xi_1\xi_2)=E(\xi_1)E(\xi_2)\)

  \(E(\xi_1)\) 顯然等於一輪抽到數字牌的期望張數 \(+1\)。 而由期望線性性,它也等於 \(n\times p+1\),其中 \(p\) 表示抽到某一張牌的概率,有:

\[p=\frac{1}{m+1} \]

  一種直觀的解釋方法是,把每張數字牌和 \(m\) 張鬼牌綁為一組,每次拿出這樣一組牌,再從中隨機選出一張作為抽到的牌,其它牌丟掉,不難證明這和原操作等價。顯然拿出某一張數字牌所在的組時,有 \(p=\frac{1}{m+1}\) 的概率真正拿到這張數字牌,不然就永遠拿不到了。於是,我們求到了:

\[E(\xi_1)=\frac{n}{m+1}+1 \]


  求 \(E(\xi_2)\),令 \(f(i)\) 表示已有 \(|S|=n-i\),到結束時的期望輪數。方程有:

\[f(i)=\frac{m}{m+i}\left(f(i)+1\right)+\frac{i}{m+i}f(i-1) \]

  特別留意上式,總牌數 \(m+i\) 是因為其他 \(n-i\) 張數字牌沒有任何意義,可以忽略;前一項抽到鬼牌,輪數才要 \(+1\);後一項抽到有用數字牌,但是這一輪並沒有結束,所以不用 \(+1\)

  整理一下:

\[f(i)=f(i-1)+\frac{m}{i} \]

  對於邊界 \(f(1)\)

,即 \(m+1\) 張裡挑出一張的期望,顯然有 \(f(1)=m+1\)。代一代求出 \(f(n)\)

\[f(n)=1+m\sum_{i=1}^n\frac1{i} \]

  綜上,答案為:

\[\begin{aligned} E(\xi_1\xi_2)&=E(\xi_1)E(\xi_2)\\ &=\left(\frac{n}{m+1}+1\right)f(n)\\ &=\left( \frac{n}{m+1}+1 \right)\left( 1+m\sum_{i=1}^n\frac1i \right) \end{aligned} \]

  計算即可。複雜度 \(\mathcal O(n+\log m)\)

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>

const int MOD = 998244353, MAXN = 2e6;
int n, m, inv[MAXN + 5];

inline int qkpow ( int a, int b, const int p = MOD ) {
	int ret = 1;
	for ( ; b; a = 1ll * a * a % p, b >>= 1 ) ret = 1ll * ret * ( b & 1 ? a : 1 ) % p;
	return ret;
}

int main () {
	scanf ( "%d %d", &n, &m );
	int turn = ( n + m + 1ll ) * qkpow ( m + 1, MOD - 2 ) % MOD, times = 1;
	for ( int i = 1; i <= n; ++ i ) {
		inv[i] = i ^ 1 ? 1ll * inv[MOD % i] * ( MOD - MOD / i ) % MOD : 1;
		times = ( times + 1ll * m * inv[i] ) % MOD;
	}
	printf ( "%d\n", int ( 1ll * turn * times % MOD ) );
	return 0;
}