codeforces 891E Lust 题解

题目传送门

题目大意: 给出一个长度为 n n n 的序列,进行 k k k 次操作,每次随机选取一个 a i a_i ai,让答案加上 a a a 序列中的其他数的乘积,然后让 a i − 1 a_i-1 ai1,问最后答案的期望。

题解

膜拜往日的神仙 OZY。

与样例快乐van耍之后,发现答案与操作顺序无关,只与每个位置被操作的次数有关。

那么不妨认为每个数都是被连续操作的,那么我们可以把一次操作的贡献看成 ( a x ∏ i ≠ x a i ) − ( ( a x − 1 ) ∏ i ≠ x a i ) (a_x\prod\limits_{i\ne x}a_i)-((a_x-1)\prod\limits_{i\ne x}a_i) (axi=xai)((ax1)i=xai),那么把 s s s 次对 x x x 的连续操作加起来,就得到了 ( a x ∏ i ≠ x a i ) − ( ( a x − s ) ∏ i ≠ x a i ) (a_x\prod\limits_{i\ne x}a_i)-((a_x-s)\prod\limits_{i\ne x}a_i) (axi=xai)((axs)i=xai)

同样的,把 k k k 次操作后的贡献加起来,就能得到 ∏ a i − ∏ ( a i − b i ) \prod a_i-\prod (a_i-b_i) ai(aibi),其中 b i b_i bi 是第 i i i 个数被操作的次数。

前面一项是固定的,只需要求后面一项的期望即可。

对每一个数 a j a_j aj 造一个生成函数, x i x^i xi 项表示这个数被操作 i i i 次,系数就是被操作 i i i 次的贡献,即 ( a j − i ) (a_j-i) (aji)

考虑到所有操作形成一个排列,一个 b b b 序列可能对应多种操作方式,所以用 E G F EGF EGF,有 f j = ∑ i = 0 ( a j − i ) x i i ! f_j=\sum\limits_{i=0}(a_j-i)\dfrac {x^i} {i!} fj=i=0(aji)i!xi

那么将所有 f j f_j fj 乘起来, x k x^k xk 那一项的系数就是答案。但是 x k x^k xk 下面有个 k ! k! k!,系数乘过来的时候得到的是 x k x^k xk 的系数,而不是 x k k ! \dfrac {x^k} {k!} k!xk 的系数,所以这一项的系数还要乘以 k ! k! k!,才是我们想要的 x k k ! \dfrac {x^k} {k!} k!xk 的系数。

并且,由于需要求的是期望,而这一项的系数是所有方案的和,所以还要除以总方案数 n k n^k nk

所以,最终的柿子为:
      k ! n k ∏ j = 1 n ( ∑ i = 0 ( a j − i ) x i i ! ) = k ! n k ∏ j = 1 n ( ∑ i = 0 a j x i i ! − ∑ i = 0 i x i i ! ) = k ! n k ∏ j = 1 n ( a j e x − ∑ i = 0 x i ( i − 1 ) ! ) = k ! n k ∏ j = 1 n ( a j e x − ∑ i = 0 x x i i ! ) = k ! n k ∏ j = 1 n ( a j − x ) e x = k ! n k e n x ∏ j = 1 n ( a j − x ) \begin{aligned} &~~~~~\frac {k!} {n^k}\prod_{j=1}^n(\sum_{i=0}(a_j-i)\frac {x^i} {i!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(\sum_{i=0}a_j\frac {x^i} {i!}-\sum_{i=0}i\frac {x^i} {i!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(a_je^{x}-\sum_{i=0}\frac {x^i} {(i-1)!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(a_je^{x}-\sum_{i=0} x \frac {x^i} {i!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(a_j-x)e^{x}\\ &=\frac {k!} {n^k} e^{nx} \prod_{j=1}^n(a_j-x)\\ \end{aligned}      nkk!j=1n(i=0(aji)i!xi)=nkk!j=1n(i=0aji!xii=0ii!xi)=nkk!j=1n(ajexi=0(i1)!xi)=nkk!j=1n(ajexi=0xi!xi)=nkk!j=1n(ajx)ex=nkk!enxj=1n(ajx)

后面的 ∏ \prod 可以 n 2 n^2 n2 暴力求,设 f [ i ] f[i] f[i] 表示求完之后的多项式的 x i x^i xi 项的系数。

由于需要求第 k k k 项的系数,而后面的 ∏ \prod 得到的是个 n n n 次的多项式,所以只需要 e n x e^{nx} enx n n n 项的系数。

最后的答案就是:
a n s = k ! n k ∑ i = 0 min ⁡ ( n , k ) f [ i ] × n k − i ( k − i ) ! = ∑ i = 0 min ⁡ ( n , k ) f [ i ] × ( k − i + 1 ) ( k − i + 2 ) . . . k n i \begin{aligned} ans&=\frac {k!} {n^k} \sum_{i=0}^{\min(n,k)} f[i]\times \frac {n^{k-i}} {(k-i)!}\\ &=\sum_{i=0}^{\min(n,k)} f[i]\times \frac {(k-i+1)(k-i+2)...k} {n^i} \end{aligned} ans=nkk!i=0min(n,k)f[i]×(ki)!nki=i=0min(n,k)f[i]×ni(ki+1)(ki+2)...k

代码如下:

#include <cstdio>
#define mod 1000000007

int n,k,f[5010],ans=0;
int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;}
inline int min(int x,int y){return x<y?x:y;}
#define inv(x) ksm(x,mod-2)

int main()
{
	scanf("%d %d",&n,&k);f[0]=1;
	for(int i=1,x;i<=n;i++){
		scanf("%d",&x);for(int j=i;j>0;j--)
		f[j]=(1ll*f[j]*x%mod-f[j-1]+mod)%mod;f[0]=1ll*f[0]*x%mod;
	}
	for(int i=0,fac=1,n_=1;i<=min(n,k);i++){
		ans=(ans+1ll*f[i]*fac%mod*inv(n_)%mod)%mod;
		fac=1ll*fac*(k-i)%mod;n_=1ll*n_*n%mod;
	}
	printf("%d",(f[0]-ans+mod)%mod);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值