题目大意
你有
n
n
n 个数
a
1
,
a
2
.
.
.
a
n
a_1,a_2...a_n
a1,a2...an
要进行
k
k
k 次操作
每次随机选择一个数
x
x
x,使得答案加上
∏
i
≠
x
a
i
\prod_{i \neq x}a_i
∏i̸=xai ,并将
a
x
a_x
ax 减去
1
1
1
求最后答案的期望,对
1
e
9
+
7
1e9+7
1e9+7 取模
Sol
设
b
i
b_i
bi 表示
i
i
i 选择了多少次
把对
a
x
a_x
ax 的一次操作的贡献看成是
∏
a
i
−
∏
a
′
i
\prod a_i−\prod a′_i
∏ai−∏a′i
其中
a
′
i
a′_i
a′i 表示将
a
x
a_x
ax 减去
1
1
1 后的数组。
连续操作后,剩下的项就只剩下
∏
a
i
−
∏
(
a
i
−
b
i
)
\prod a_i−\prod(a_i−b_i)
∏ai−∏(ai−bi)
考虑计算
∏
(
a
i
−
b
i
)
\prod(a_i−b_i)
∏(ai−bi) 的期望
考虑生成函数
答案就是
∏
i
=
1
n
(
∑
j
=
0
∞
a
i
−
j
j
!
x
j
)
[
x
k
]
\prod_{i=1}^{n}(\sum_{j=0}^{\infty}\frac{a_i-j}{j!}x^j)[x^k]
i=1∏n(j=0∑∞j!ai−jxj)[xk]
[
x
k
]
[x^k]
[xk] 表示
x
k
x^k
xk 的系数,最后乘上
k
!
k!
k! 和
1
n
k
\frac{1}{n^k}
nk1
那一坨东西化简一下就是
e
n
x
∏
i
=
1
n
(
a
i
−
x
)
e^{nx}\prod_{i=1}^{n}(a_i-x)
enxi=1∏n(ai−x)
e
n
x
e^{nx}
enx 直接泰勒展开求就好了,后面的直接分治NTT暴力卷起来就好了
最后把两个多项式再卷一下
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod(1e9 + 7);
const int maxn(5005);
inline void Inc(int &x, int y) {
if ((x += y) >= mod) x -= mod;
}
inline int Pow(ll x, int y) {
register ll ret = 1;
for (; y; y >>= 1, x = x * x % mod)
if (y & 1) ret = ret * x % mod;
return ret;
}
int f[maxn], n, k, ans;
int main() {
register int i, j, a, fac, cur;
scanf("%d%d", &n, &k), f[0] = 1;
for (i = 1; i <= n; ++i) {
scanf("%d", &a);
for (j = i; j; --j) f[j] = 1LL * f[j] * a % mod, Inc(f[j], mod - f[j - 1]);
f[0] = 1LL * f[0] * a % mod;
}
a = Pow(n, 1LL * k * (mod - 2) % (mod - 1)), cur = Pow(n, k - min(n, k));
for (fac = 1, i = k - min(n, k) + 1; i <= k; ++i) fac = 1LL * fac * i % mod;
for (i = min(n, k); ~i; --i) {
Inc(ans, 1LL * f[i] * fac % mod * cur % mod);
cur = 1LL * cur * n % mod, fac = 1LL * fac * Pow(k - i + 1, mod - 2) % mod;
}
ans = 1LL * ans * a % mod, ans = (f[0] - ans + mod) % mod;
printf("%d\n", ans);
return 0;
}