题意
有
n
n
n件物品,某一时刻出现物品
i
i
i的概率为
p
i
m
\frac{p_i}{m}
mpi,求收集到至少
k
k
k件物品的期望时间。
k
≤
n
≤
1000
,
m
≤
10000
,
∑
p
i
=
m
,
n
−
k
≤
10
k\le n\le 1000,m\le10000,\sum p_i=m,n-k\le 10
k≤n≤1000,m≤10000,∑pi=m,n−k≤10
kth min-max容斥
min-max容斥:
max
(
S
)
=
∑
T
⊆
S
(
−
1
)
∣
T
∣
−
1
min
(
T
)
\max(S)=\sum_{T\subseteq S}(-1)^{|T|-1}\min(T)
max(S)=T⊆S∑(−1)∣T∣−1min(T)
现在要推广到求
S
S
S得第
k
k
k大的元素,设大小为
m
m
m的集合的容斥系数为
f
(
m
)
f(m)
f(m),那么有
k
t
h
max
(
S
)
=
∑
T
⊆
S
f
(
∣
T
∣
)
min
(
T
)
kth\max(S)=\sum_{T\subseteq S}f(|T|)\min(T)
kthmax(S)=T⊆S∑f(∣T∣)min(T)
对于第
m
+
1
m+1
m+1大的元素,其对等号右边式子贡献的系数为
∑
i
=
0
m
(
m
i
)
f
(
i
+
1
)
\sum_{i=0}^m\binom{m}{i}f(i+1)
i=0∑m(im)f(i+1)
那么对于容斥系数
f
(
m
)
f(m)
f(m)要满足
[
m
=
i
−
1
]
=
∑
i
=
0
m
(
m
i
)
f
(
i
+
1
)
[m=i-1]=\sum_{i=0}^m\binom{m}{i}f(i+1)
[m=i−1]=i=0∑m(im)f(i+1)
二项式反演可得
f
(
m
+
1
)
=
∑
i
=
0
m
(
−
1
)
m
−
i
(
m
i
)
[
i
=
k
−
1
]
=
(
−
1
)
m
−
k
+
1
(
m
k
−
1
)
f(m+1)=\sum_{i=0}^m(-1)^{m-i}\binom{m}{i}[i=k-1]=(-1)^{m-k+1}\binom{m}{k-1}
f(m+1)=i=0∑m(−1)m−i(im)[i=k−1]=(−1)m−k+1(k−1m)
所以容斥系数为
f
(
m
)
=
(
−
1
)
m
−
k
(
m
−
1
k
−
1
)
f(m)=(-1)^{m-k}\binom{m-1}{k-1}
f(m)=(−1)m−k(k−1m−1)
于是有
k
t
h
max
(
S
)
=
∑
T
⊆
S
(
−
1
)
∣
T
∣
−
k
(
∣
T
∣
−
1
k
−
1
)
min
(
T
)
kth\max(S)=\sum_{T\subseteq S}(-1)^{|T|-k}\binom{|T|-1}{k-1}\min(T)
kthmax(S)=T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)min(T)
分析
通过kth min-max容斥转为求
∑
T
⊆
S
(
−
1
)
∣
T
∣
−
k
(
∣
T
∣
−
1
k
−
1
)
min
(
T
)
\sum_{T\subseteq S}(-1)^{|T|-k}\binom{|T|-1}{k-1}\min(T)
T⊆S∑(−1)∣T∣−k(k−1∣T∣−1)min(T)
显然
min
(
T
)
=
m
∑
i
∈
T
p
i
\min(T)=\frac{m}{\sum_{i\in T}p_i}
min(T)=∑i∈Tpim
设
f
i
,
j
,
k
f_{i,j,k}
fi,j,k表示前
i
i
i种物品,满足
∑
x
∈
T
p
x
=
j
\sum_{x\in T}p_x=j
∑x∈Tpx=j且参数为
k
k
k时的
(
−
1
)
∣
T
∣
−
k
(
∣
T
∣
−
1
k
−
1
)
(-1)^{|T|-k}\binom{|T|-1}{k-1}
(−1)∣T∣−k(k−1∣T∣−1)之和
转移的时候考虑是否加入第
i
i
i种物品
若不加入,则
f
i
,
j
,
k
=
f
i
−
1
,
j
,
k
f_{i,j,k}=f_{i-1,j,k}
fi,j,k=fi−1,j,k
若加入,可以发现
(
∣
T
∣
−
1
k
−
1
)
=
(
∣
T
∣
−
2
k
−
1
)
+
(
∣
T
∣
−
2
k
−
2
)
\binom{|T|-1}{k-1}=\binom{|T|-2}{k-1}+\binom{|T|-2}{k-2}
(k−1∣T∣−1)=(k−1∣T∣−2)+(k−2∣T∣−2)
右边两项分别对应
f
i
−
1
,
j
−
p
i
,
k
,
f
i
−
1
,
j
−
p
i
,
k
−
1
f_{i-1,j-p_i,k},f_{i-1,j-p_i,k-1}
fi−1,j−pi,k,fi−1,j−pi,k−1
由于系数的正负号由
k
k
k和
∣
T
∣
|T|
∣T∣来决定,现在集合大小减1,所以
f
i
−
1
,
j
−
p
i
,
k
f_{i-1,j-p_i,k}
fi−1,j−pi,k的系数为负,
f
i
−
1
,
j
−
p
i
,
k
−
1
f_{i-1,j-p_i,k-1}
fi−1,j−pi,k−1的系数为正。
于是
f
i
,
j
,
k
=
f
i
−
1
,
j
−
p
i
,
k
−
1
−
f
i
−
1
,
j
−
p
i
,
k
f_{i,j,k}=f_{i-1,j-p_i,k-1}-f_{i-1,j-p_i,k}
fi,j,k=fi−1,j−pi,k−1−fi−1,j−pi,k
时间复杂度
O
(
n
m
(
n
−
k
)
)
O(nm(n-k))
O(nm(n−k))
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
typedef long long LL;
const int N=1005;
const int MOD=998244353;
int n,k,m,p[N],f[2][N*10][15];
int ksm(int x,int y)
{
int ans=1;
while (y)
{
if (y&1) ans=(LL)ans*x%MOD;
x=(LL)x*x%MOD;y>>=1;
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&k,&m);
k=n-k+1;
for (int i=1;i<=n;i++) scanf("%d",&p[i]);
f[0][0][0]=1;
int now=0;
for (int i=1;i<=n;i++)
{
now^=1;
for (int j=0;j<=m;j++)
for (int l=0;l<=k;l++)
{
f[now][j][l]=f[now^1][j][l];
if (l&&j>=p[i]) (f[now][j][l]+=f[now^1][j-p[i]][l-1]-f[now^1][j-p[i]][l])%=MOD,f[now][j][l]+=f[now][j][l]<0?MOD:0;
}
}
int ans=0;
for (int i=1;i<=m;i++) (ans+=(LL)f[now][i][k]*ksm(i,MOD-2)%MOD)%=MOD;
printf("%d\n",(LL)ans*m%MOD);
return 0;
}