Description
有n种物品,每次操作你有
p
i
m
pi\over m
mpi的概率获得第i种物品
求你获得k种物品的期望操作数。
n<=1000,n-k<=10,m<=10000
Solution
考虑第i个物品的EGF为
e
p
i
m
x
−
1
e^{{p_i\over m}x}-1
empix−1
枚举最后一个出现的物品为s,令
F
s
(
x
)
=
∑
∣
a
∣
=
k
−
1
,
s
∉
a
∏
j
=
1
k
−
1
(
e
p
j
m
x
−
1
)
F_s(x)=\sum_{|a|=k-1,s\notin a}\prod_{j=1}^{k-1}(e^{{p_j\over m}x}-1)
Fs(x)=∣a∣=k−1,s∈/a∑j=1∏k−1(empjx−1)
我们要求的就是
p
s
m
∑
i
>
=
0
[
x
i
]
F
s
(
x
)
i
!
∗
i
{p_s\over m}\sum_{i>=0}[x^i]F_s(x)i!*i
mpsi>=0∑[xi]Fs(x)i!∗i
考虑把F(x)写成
∑
a
i
e
b
i
m
x
\sum a_ie^{{b_i\over m}x}
∑aiembix
对于一个
e
n
m
x
e^{{n\over m}x}
emnx对于答案的贡献为
∑
i
>
=
0
(
n
m
)
i
i
!
∗
i
!
∗
(
i
+
1
)
\sum_{i>=0}{({n\over m})^i\over i!}*i!*(i+1)
i>=0∑i!(mn)i∗i!∗(i+1)
=
∑
i
>
=
0
(
n
m
)
i
(
i
+
1
)
=\sum_{i>=0}({n\over m})^i(i+1)
=i>=0∑(mn)i(i+1)
=
(
m
m
−
n
)
2
=({m\over m-n})^2
=(m−nm)2
考虑如何求F(x),先不管i不能选的限制,求出F[k][j]表示当前有k个多项式没有选择,剩下的多项式的乘积
然后每一次对于枚举的i,从F[k][j]中将i的贡献删去,统计答案之后再加回来
复杂度O(n(n-k)m)
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N=1e4+5,Mo=998244353;
int inc(int x,int y) {return x+y>=Mo?x+y-Mo:x+y;}
int dec(int x,int y) {return x-y<0?x-y+Mo:x-y;}
int n,m,k,p[N],f[15][N],inv[N];
int main() {
scanf("%d%d%d",&n,&k,&m);k=n-k;
fo(i,1,n) scanf("%d",&p[i]);
inv[1]=1;fo(i,2,m) inv[i]=(ll)(Mo-Mo/i)*inv[Mo%i]%Mo;
f[0][0]=1;
fo(i,1,n) {
fd(w,k,0)
fd(j,m,0) {
f[w][j]=dec(0,f[w][j]);
if (j>=p[i]) f[w][j]=inc(f[w][j],f[w][j-p[i]]);
if (w) f[w][j]=inc(f[w][j],f[w-1][j]);
}
}
int ans=0;
fo(i,1,n) {
fo(j,0,m)
fo(w,0,k) {
if (w) f[w][j]=dec(f[w][j],f[w-1][j]);
if (j>=p[i]) f[w][j]=dec(f[w][j],f[w][j-p[i]]);
f[w][j]=dec(0,f[w][j]);
}
int res=f[k][0];
fo(j,1,m-p[i]) {
int p=(ll)m*inv[m-j]%Mo;
res=inc(res,(ll)f[k][j]*p%Mo*p%Mo);
}
ans=inc(ans,(ll)res*p[i]%Mo*inv[m]%Mo);
fd(w,k,0)
fd(j,m,0) {
f[w][j]=dec(0,f[w][j]);
if (j>=p[i]) f[w][j]=inc(f[w][j],f[w][j-p[i]]);
if (w) f[w][j]=inc(f[w][j],f[w-1][j]);
}
}
printf("%d\n",ans);
return 0;
}