设
bi
b
i
表示
ai
a
i
减了几次,那么答案就是
∏ni=1ai−∏ni=1(ai−bi)
∏
i
=
1
n
a
i
−
∏
i
=
1
n
(
a
i
−
b
i
)
。可以对每次操作分开计算贡献得到。
然后就是怎么求
∏ni=1(ai−bi)
∏
i
=
1
n
(
a
i
−
b
i
)
的期望。令
k=∑bi
k
=
∑
b
i
。
然后考虑怎么求 ∏ni=1(ai−bi)bi! ∏ i = 1 n ( a i − b i ) b i ! 。
构造生成函数:
令 G(x)=∏ni=1(ai−x)=∑ni=0cixi G ( x ) = ∏ i = 1 n ( a i − x ) = ∑ i = 0 n c i x i 。
其中 ci c i 可以 O(n2) O ( n 2 ) 求出。
然后就好了。
#include<bits/stdc++.h>
using namespace std;
const int N=5010;
const int M=1000000007;
int k,n,m,x,Ans,s=1;
int c[N],d[N];
inline void Add(int& x,int y){
x=(x+y)%M;
}
inline int Pow(int x,int y){
int Ans=1;
for(;y;y>>=1,x=1ll*x*x%M)
if(y&1)Ans=1ll*Ans*x%M;
return Ans;
}
int main(){
scanf("%d%d",&n,&k);
c[0]=1;
for(int i=1;i<=n;i++){
scanf("%d",&x);
s=1ll*s*x%M;
for(int j=0;j<i;j++)d[j]=1ll*c[j]*x%M;
for(int j=0;j<i;j++)Add(d[j+1],-c[j]);
memcpy(c,d,sizeof(d));
}
int inv=Pow(n,M-2);
for(int i=0,t=1,T=1;i<=n;i++){
Add(Ans,1ll*c[i]*T%M*t%M);
t=1ll*t*inv%M;T=1ll*T*(k-i)%M;
}
Add(s,-Ans);
cout<<(s+M)%M<<endl;
return 0;
}