题目大意
有n个数,进行k轮操作:随机一个i,让
ai
a
i
减1,然后ans加上
Πj≠iai
Π
j
≠
i
a
i
。
求ans的期望。
分析
发现,造成的伤害就是原来的ai的积减去k轮操作后的ai的积(其实我在看题解前根本没发现)。
题目就变成了求k轮操作后的ai的积的期望。
设ai经过了k轮操作减去了bi
E(Πni=1(ai−bi))=1nk∑∑ni=1bi=kΠni=1(ai−bi)(ai−bi)Cb1kCb2k−b1Cb3k−b1−b2...
E
(
Π
i
=
1
n
(
a
i
−
b
i
)
)
=
1
n
k
∑
∑
i
=
1
n
b
i
=
k
Π
i
=
1
n
(
a
i
−
b
i
)
(
a
i
−
b
i
)
C
k
b
1
C
k
−
b
1
b
2
C
k
−
b
1
−
b
2
b
3
.
.
.
=1nk∑∑ni=1bi=kΠni=1(ai−bi)(ai−bi)k!Πni=1bi!
=
1
n
k
∑
∑
i
=
1
n
b
i
=
k
Π
i
=
1
n
(
a
i
−
b
i
)
(
a
i
−
b
i
)
k
!
Π
i
=
1
n
b
i
!
考虑如何求
∑∑ni=1bi=kΠni=1(ai−bi)(ai−bi)1Πni=1bi!
∑
∑
i
=
1
n
b
i
=
k
Π
i
=
1
n
(
a
i
−
b
i
)
(
a
i
−
b
i
)
1
Π
i
=
1
n
b
i
!
设生成函数
Fi(x)=∑j=0∞ai−jj!xj=∑j=0∞aij!xj−∑j=0∞1(j−1)!xj=(ai−x)ex
F
i
(
x
)
=
∑
j
=
0
∞
a
i
−
j
j
!
x
j
=
∑
j
=
0
∞
a
i
j
!
x
j
−
∑
j
=
0
∞
1
(
j
−
1
)
!
x
j
=
(
a
i
−
x
)
e
x
于是就
=Πni=1Fi(x)=enxΠni=1(ai−x)
=
Π
i
=
1
n
F
i
(
x
)
=
e
n
x
Π
i
=
1
n
(
a
i
−
x
)
我们就要求出 enxΠni=1(ai−x) e n x Π i = 1 n ( a i − x ) 的第k项的系数
Πni=1(ai−x) Π i = 1 n ( a i − x ) 就可以用分治FFT来求。
然后对于 Πni=1(ai−x) Π i = 1 n ( a i − x ) 第i项乘上 enx e n x 第k-i项加起来就是 enxΠni=1(ai−x) e n x Π i = 1 n ( a i − x ) 的第k项的系数了。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <bitset>
#include <set>
#include <vector>
const int inf=2147483647;
const long long mo=998244353;
const int N=400005;
using namespace std;
long long f[20][N],W[N];
int n,m;
long long ans,a[N],ny;
long long poww(long long x,long long y)
{
long long s=1;
for(;y;y>>=1,x=x*x%mo)
if(y&1) s=s*x%mo;
return s;
}
void NTT(long long *f,int fn,int z)
{
for(int i=0,p=0;i<fn;i++)
{
if(i<p) swap(f[i],f[p]);
for(int j=fn>>1;(p^=j)<j;j>>=1);
}
for(int i=2;i<=fn;i<<=1)
{
int half=i>>1,pe=fn/i;
for(int j=0;j<half;j++)
{
long long w0=z?W[j*pe]:W[fn-j*pe];
for(int k=j;k<fn;k+=i)
{
long long x=f[k],y=f[k+half]*w0%mo;
f[k]=(x+y)%mo,f[k+half]=(x-y+mo)%mo;
}
}
}
}
void dc(int deep,int l,int r)
{
if(l==r)
{
f[deep][0]=a[l],f[deep][1]=-1;
return;
}
int mid=(l+r)>>1,fn;
for(fn=1;fn<=r-l+2;fn<<=1);
dc(deep+1,l,mid);
for(int i=0;i<fn;i++) f[deep][i]=f[deep+1][i],f[deep+1][i]=0;
dc(deep+1,mid+1,r);
W[0]=1,W[1]=poww(3,(mo-1)/fn);
for(int i=1;i<=fn;i++) W[i]=W[i-1]*W[1]%mo;
NTT(f[deep],fn,1),NTT(f[deep+1],fn,1);
for(int i=0;i<fn;i++) f[deep][i]=f[deep][i]*f[deep+1][i]%mo;
NTT(f[deep],fn,0);
ny=poww(fn,mo-2);
for(int i=0;i<fn;i++) f[deep][i]=f[deep][i]*ny%mo;
for(int i=0;i<fn;i++) f[deep+1][i]=0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
dc(1,1,n);
long long val=m;
ny=poww(n,mo-2);
for(int i=1;i<=min(n,m);i++)
{
val=val*ny%mo;
ans=(ans+f[1][i]*val%mo)%mo;
if(m-i>=1) val=val*(m-i)%mo;
}
printf("%lld\n",(mo-ans+mo)%mo);
}