题目大意
一个序列a,做k次下列操作:
1、随机一个下标x,答案加上
Πni=1,i!=xai
2、将
ax
减一。
求答案的期望。
做法
设
bi
表示最终
ai
减少了多少次。
答案是
Πni=1ai−Πni=1(ai−bi)
E(Πni=1ai−Πni=1(ai−bi))=Πni=1ai−k!∑∑ni=1bi=kΠni=1(ai−bi)bi!nk
只考虑计算后面部分。
设
F(x)=Πni=1∑j>=0xj∗(ai−j)j!
这是后面那个东西的生成函数。
F(x)=Πni=1ex(ai−x)
F(x)=enxΠni=1(ai−x)
对于后面部分我们暴力展开得到
∑ni=0cixi
现在
[xk]F(x)=∑ni=0cink−i(k−i)!
代入原式得到
∑ni=0ciΠkj=k−i+1jni
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=5000+10,mo=1000000007;
int c[maxn],d[maxn],a[maxn];
int i,j,k,l,t,n,m,ni,num,ans;
int qsm(int x,int y){
if (!y) return 1;
int t=qsm(x,y/2);
t=(ll)t*t%mo;
if (y%2) t=(ll)t*x%mo;
return t;
}
int main(){
scanf("%d%d",&n,&k);
c[0]=1;
fo(i,1,n){
scanf("%d",&a[i]);
fo(j,0,i) d[j]=0;
fo(j,0,i-1){
(d[j]+=(ll)c[j]*a[i]%mo)%=mo;
(d[j+1]-=c[j])%=mo;
}
fo(j,0,i) c[j]=d[j];
}
ni=qsm(n,mo-2);
num=1;
fo(i,0,n){
(ans+=(ll)c[i]*num%mo)%=mo;
num=(ll)num*ni%mo*(k-i)%mo;
}
ans=(c[0]-ans)%mo;
(ans+=mo)%=mo;
printf("%d\n",ans);
}