zoukankan      html  css  js  c++  java
  • 【CF891E】Lust 生成函数

    【CF891E】Lust

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

    $nle 5000,kle 10^9$

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

    于是问题就变成了求$[{sum b_i=k}]{1over n^k}{k!over prod b_i!}prodlimits_{i}(a_i-b_i)$

    设生成函数$F_i(x)=sumlimits_{j}{(a_i-j)x^jover j!}$,它等于

    $F_i(x)=sumlimits_j{a_ix^jover j!}-sumlimits_j{x^jover (j-1)!}\=sumlimits_{j}{a_ix^jover j!}-xsumlimits_{j}{x^jover j!}\=sumlimits_j{(a_i-x)x^jover j!}=(a_i-x)e^j$

    所以$prodlimits_i F_i(x)=e^{nj}prodlimits_i (a_i-x)$。我们可以暴力求出$prodlimits_i (a_i-x)$的每一项系数,设其为$c_i$。剩下的就是求$e^{nj}$的第$k-n,k-n+1...k$项系数。显然第i项系数是$n^iover i!$,再乘上前面的${k!over n^k}$就变成了$sumlimits_{i=0}^n{c_i}n^{-i}prodlimits_{j=k-i}^kj$

    #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;
    }
  • 相关阅读:
    Redis的特点什么是?
    Linux---用户和用户管理--用户配置文件
    python---模仿键盘
    Linux---脚本安装包
    python---创建句柄
    python---模仿鼠标悬停 move_to_element/perform/context_click
    python---总结所学元素及方法
    python---关闭 close,quit
    python---截屏
    python---前进和后退 back/forward
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8594955.html
Copyright © 2011-2022 走看看