codeforces891ELust

题意:

一个序列a,做k次下列操作:
1、随机一个下标 x x x,答案加上 Π i = 1 , i ! = x n a i \Pi_{i=1,i!=x}^na_i Πi=1,i!=xnai
2、将 a x a_x ax减一。
求答案的期望。

题解:

感受一下,可以发现答案是这个 Π a i − Π ( a i − b i ) \Pi a_i-\Pi(a_i-b_i) ΠaiΠ(aibi)
其中 b i b_i bi表示 i i i被减了几次。
那么设 F i ( x ) F_i(x) Fi(x)表示 a [ i ] a[i] a[i]被减去 b [ i ] b[i] b[i]之后对答案的贡献
F i ( x ) = ∑ j > 0 ( a i − j ) x j j ! F_i(x)=\sum_{j>0}\frac{(a_i-j)x^j}{j!} Fi(x)=j>0j!(aij)xj
整体还要乘 k ! k! k!,除阶乘就可以除额外去贡献
F i ( x ) = ( a i − x ) e x F_i(x)=(a_i-x)e^x Fi(x)=(aix)ex

这个可以用泰勒展开验证
F ( x ) = e n x Π i = 1 n ( a i − x ) F(x)=e^{nx}\Pi_{i=1}^n(a_i-x) F(x)=enxΠi=1n(aix)

因为 e n x = ∑ i = 0 ( n x ) i i ! e^{nx}=\sum_{i=0}\frac{(nx)^i}{i!} enx=i=0i!(nx)i,后面那部分暴力展开为 ∑ i = 0 n c i x i \sum_{i=0}^nc_ix^i i=0ncixi然后再暴力卷起来,设第i项系数为 C i C_i Ci
代入得 ∑ i = 0 n C i Π j = k − i + 1 k j n i \sum_{i=0}^nC_i\frac{\Pi_{j=k-i+1}^kj}{n^i} i=0nCiniΠj=ki+1kj
code:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#define LL long long
using namespace std;
const LL mod=1e9+7;
LL n,m,a[5010],d[5010],c[5010],k;
LL Pow(LL a,LL b)
{
	LL ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;b>>=1;
	}
	return ans;
}
int main()
{
	scanf("%lld %lld",&n,&k);
	c[0]=1;
	for(LL i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		memset(d,0,sizeof(d));
		for(LL j=0;j<i;j++)
		{
			(d[j]+=c[j]*a[i]%mod)%=mod;
            (d[j+1]-=c[j])%=mod;
		}
		memcpy(c,d,sizeof(c));
	}
	LL inv=Pow(n,mod-2),num=1,ans=0;
	for(LL i=0;i<=n;i++)
	{
        (ans+=c[i]*num%mod)%=mod;
        num=num*inv%mod*(k-i)%mod;
    }
    ans=(c[0]-ans)%mod;
    printf("%lld\n",(ans+mod)%mod);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值