有一n*m的棋盘,每次随机染黑一个位置(可能染到已经黑了的),当某一行或者一列全为黑色时停止,求期望染色次数(mod 998244353)
对于100%的数据n,m<=1000
考完听说是模板题
显然这个“当xxx时停止”非常不好处理,我们不知道它到底有没有停止,方案也很难统计。
不考虑停止,一直染,用
a
1
,
a
2
…
a
n
a_1,a_2\dots a_n
a1,a2…an表示
a
i
a_i
ai行全黑时的次数,用
b
j
b_j
bj表示
b
j
b_j
bj列全黑时的次数。
我们想知道
E
(
min
{
a
1
,
a
2
…
a
n
,
b
1
,
b
2
…
b
m
}
)
E\left(\min\{a_1,a_2\dots a_n,b_1,b_2\dots b_m\}\right)
E(min{a1,a2…an,b1,b2…bm})
上minmax反演:
min
(
S
)
=
∑
T
⊆
S
,
T
≠
∅
(
−
1
)
∣
T
∣
−
1
max
(
T
)
\min(S)=\sum_{T\subseteq S,T\ne\empty}(-1)^{|T|-1}\max(T)
min(S)=T⊆S,T̸=∅∑(−1)∣T∣−1max(T)
证明:设
s
1
≤
s
2
⋯
≤
s
N
s_1\le s_2\dots\le s_N
s1≤s2⋯≤sN,考虑
s
i
s_i
si在右式的贡献:
s
i
s_i
si作为max,剩下的数在
s
1
s_1
s1到
s
i
−
1
s_{i-1}
si−1随便选。当
i
>
1
i>1
i>1时,集合数为
2
i
−
1
2^{i-1}
2i−1,集合奇偶各占一半,相互抵消;当
i
=
1
i=1
i=1时,集合数为1,贡献为
s
1
s_1
s1,得证。
在外面套上一个期望,上式仍然成立。
选出
i
i
i行,
j
j
j列,
a
,
b
a,b
a,b的max就是把这
i
i
i行
j
j
j列全部染黑的次数,总个数是
k
=
i
m
+
j
n
−
i
j
k=im+jn-ij
k=im+jn−ij,染到第一个的概率是
k
n
m
\frac k{nm}
nmk,期望次数就是
n
m
k
\frac {nm}k
knm,染第二个的期望次数就是
n
m
k
−
1
\frac {nm}{k-1}
k−1nm。所以
E
(
min
(
a
.
.
,
b
.
.
)
)
=
∑
i
=
0
n
∑
j
=
0
m
[
i
∣
∣
j
]
(
n
i
)
(
m
j
)
n
m
(
1
+
1
2
+
.
.
.
+
1
i
m
+
j
n
−
i
j
)
E(\min(a..,b..))=\sum_{i=0}^n\sum_{j=0}^m[i||j]{n\choose i}{m\choose j}nm(1+\frac 12+...+\frac 1{im+jn-ij})
E(min(a..,b..))=i=0∑nj=0∑m[i∣∣j](in)(jm)nm(1+21+...+im+jn−ij1)
Code:
#include<bits/stdc++.h>
#define maxn 1005
using namespace std;
const int mod = 998244353;
int n,m,ans,c[maxn][maxn],inv[maxn*maxn],s[maxn*maxn];
int main()
{
freopen("wait.in","r",stdin);
freopen("wait.out","w",stdout);
scanf("%d%d",&n,&m);
c[0][0]=1;
for(int i=1;i<=max(n,m);i++){
c[i][0]=c[i][i]=1;
for(int j=1;j<i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
inv[0]=inv[1]=1,s[1]=n*m;
for(int i=2;i<=n*m;i++)
inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod,
s[i]=(s[i-1]+1ll*n*m*inv[i])%mod;
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++) if(i||j)
ans=(ans+1ll*((i+j)&1?1:-1)*c[n][i]*c[m][j]%mod*s[i*m+j*n-i*j])%mod;
printf("%d\n",(ans+mod)%mod);
}