Processing math: 100%

【CF891E】Lust 生成函数

【CF891E】Lust

题意:给你一个长度为n的序列ai,对这个序列进行k次操作,每次随机选择一个1到n的数x,令res+=i!=xai(一开始res=0),然后ai--。问最终res的期望值。答案在模意义下对109+7取模。

n5000,k109

题解:首先需要发现,假如第i个数被减的次数为bi,则res=iaii(aibi)。这个用归纳法容易证明。

于是问题就变成了求[bi=k]1nkk!bi!i(aibi)

设生成函数Fi(x)=j(aij)xjj!,它等于

Fi(x)=jaixjj!jxj(j1)!=jaixjj!xjxjj!=j(aix)xjj!=(aix)ej

所以iFi(x)=enji(aix)。我们可以暴力求出i(aix)的每一项系数,设其为ci。剩下的就是求enj的第kn,kn+1...k项系数。显然第i项系数是nii!,再乘上前面的k!nk就变成了ni=0cinikj=kij

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=5010;
typedef long long ll;
const ll P=1000000007;
ll ine[maxn],v[maxn],f[maxn];
int n;
ll k,ans;
int main()
{
    int i,j;
    scanf("%d%lld",&n,&k);
    for(ans=i=1;i<=n;i++)    scanf("%lld",&v[i]),ans=ans*v[i]%P;
    f[0]=1;
    for(i=1;i<=n;i++)
    {
        for(j=i;j>=1;j--)
        {
            f[j]=(f[j]*v[i]-f[j-1])%P;
        }
        f[0]=f[0]*v[i]%P;
    }
    ine[0]=ine[1]=1;
    for(i=2;i<=n;i++)    ine[i]=P-(P/i)*ine[P%i]%P;
    ll t=1,tmp=1;
    for(i=0;i<=n&&i<=k;i++)
    {
        ans=(ans-f[i]*t%P*tmp)%P;
        t=t*ine[n]%P,tmp=tmp*(k-i)%P;
    }
    printf("%lld",(ans+P)%P);
    return 0;
}
posted @   CQzhangyu  阅读(842)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示