cf891E Lust

非常有趣(
考虑设 b n b_n bn为第 n n n个数被减去的次数,那么对于 K K K次之后的某个局面,答案就是
∏ i = 1 n a i − ∏ i = 1 n ( a i − b i ) \prod_{i=1}^n a_i - \prod_{i=1}^n (a_i-b_i) i=1naii=1n(aibi)
的期望值
实际上就是
∏ i = 1 n a i − ∑ ∑ b i = k k ! n k ∏ i = 1 n b i ! ∏ i = 1 n ( a i − b i ) \prod_{i=1}^n a_i - \sum_{\sum b_i=k} \frac{k!}{n^k \prod_{i=1}^n b_i!} \prod_{i=1}^n (a_i-b_i) i=1naibi=knki=1nbi!k!i=1n(aibi)
也就是说,我们把 b i ! b_i! bi!挪进去,对于 ∑ ∑ b i = k ∏ i = 1 n a i − b i b i ! \sum_{\sum b_i=k}\prod_{i=1}^n \frac{a_i-b_i}{b_i!} bi=ki=1nbi!aibi计算贡献
这一块的贡献我们可以考虑生成函数,对于每一个 a i − b i b i ! \frac{a_i-b_i}{b_i!} bi!aibi,他的生成函数就是
F i ( x ) = ∑ j = 0 ∞ ( a i − j ) x j j ! F_i(x)=\sum_{j=0}^{\infin} \frac{(a_i-j)x^j}{j!} Fi(x)=j=0j!(aij)xj
大力化简一下,就是 F i ( x ) = ( a i − x ) e x F_i(x) = (a_i-x) e^x Fi(x)=(aix)ex
然后我们乘一下,那么 F i ( x ) = e n x ∏ i = 1 n ( a i − x ) F_i(x)=e^{nx}\prod_{i=1}^n(a_i-x) Fi(x)=enxi=1n(aix)
然后前面的展开,后面的暴力
记得乘上 k ! n k \frac{k!}{n^k} nkk!
如果把生成函数乘完之后的系数设为 c i , c_i , ci,这样答案就是
∑ i = 0 n c i ∏ j = k − i + 1 k j n i \sum_{i=0}^n c_i \frac{\prod_{j=k-i+1}^{k} j}{n^i} i=0ncinij=ki+1kj

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

#define SZ(x) ((int)(x).size())

using ll = long long;

ll KSM(ll a, ll k, ll mod) {
	ll ret = 1 % mod;
	for (; k; k >>= 1, a = a * a % mod) 
		if (k & 1)
			ret = ret * a % mod;
	return ret;
}

vector<int> mul(vector<int> const& f, vector<int> const& f2, int const& mod) {
	auto ret = vector<int>(SZ(f) + SZ(f2) - 1, 0);
	for (int i = 0; i < SZ(f); ++i) 
		for (int j = 0; j < SZ(f2); ++j) 
			ret[i + j] = (ret[i + j] + 1LL * f[i] * f2[j] % mod) % mod;
	return ret;
}
 
int const N = 5005;
int const mod = 1e9 + 7;

int a[N];
int n, K;

int main() {
	cin >> n >> K;
	for (int i = 1; i <= n; ++i) 
		cin >> a[i];
	auto f = vector<int>(1, 0);
	f[0] = 1;
	long long ans = 1;
	for (int i = 1; i <= n; ++i) {
		auto t = vector<int>(2, 0);
		t[0] = a[i];
		t[1] = -1;
		f = mul(f, t, mod);
		ans = ans * a[i] % mod;
	}
	long long jc = 1, inv = 1;
	long long inv_n = KSM(n, mod - 2, mod);
	for (int i = 0; i <= n; ++i) {
		ans = (ans - 1LL * f[i] * jc % mod * inv % mod) % mod;
		jc = jc * (K - i) % mod;
		inv = inv * inv_n % mod;
	}
	cout << (ans % mod + mod) % mod << '\n';
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值