[EGF] CF891E Lust

\(\texttt{link}\)

每次操作相当于给 \(res\) 加上 \(\Delta\prod\limits_{i=1}^na_i\),那么最终的 \(res\) 即为 \(\prod\limits_{i=1}^na'_i - \prod\limits_{i=1}^na_i\)

写出答案的柿子: \(ans = \prod\limits_{i=1}^na_i - \dfrac {k!} {n^k}\prod\limits_{i=1}^n\dfrac{a_i - b_i}{b_i!}\)

只考虑计算后面的柿子,记 \(\hat{F_i}(x) = \sum\limits_{i=1}^{+\infty}\dfrac{(a_i-j)x^j}{j!}\)

拆开,\(\hat{F_i}(x) = \sum\limits_{i=1}^{+\infty}(\dfrac{a_ix^j}{j!} - \dfrac{x\cdot x^{j-1}}{(j-1)!}) =(a_i-x)e^x\)

后式 \(=\dfrac {k!} {n^k}[x^k]\prod\limits_{i=1}^nF_i(x) = \dfrac {k!} {n^k}[x^k]e^{nx}\prod\limits_{i=1}^n(a_i-x)\)

暴力卷出 \(F(x) = \prod\limits_{i=1}^n(a_i-x)\),答案即为 \(\prod\limits_{i=1}^na_i - \dfrac{1}{n^k}\sum\limits_{i=0}^{\min(n,k)}F(i)n^{k-i}k^{\underline{i}}\)

\(\texttt{Code:}\)

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
int read() {
    int x = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= c == '-', c = getchar();
    while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
    return f ? -x : x;
}
const int cmd = 1e9 + 7;
int add(int a, int b) {a += b; return a < cmd ? a : a - cmd;}
int sub(int a, int b) {a -= b; return a < 0 ? a + cmd : a;}
int mul(int a, int b) {return 1ll * a * b % cmd;}
int fpow(int a, int b) {
    int res = 1;
    for (; b; b >>= 1, a = mul(a, a))
        if (b & 1) res = mul(res, a);
    return res;
}
const int N = 5e3 + 5;
int n, k, a[N], ans;
int C(int n, int m) {
    int res = 1;
    for (int i = n; i >= n - m + 1; i--) res = mul(res, i);
    for (int i = 2; i <= m; i++) res = mul(res, fpow(i, cmd - 2));
    return res;
}
#define poly vector<int>
#define sz(f) (int)(f.size())
poly f;
namespace Poly {
    poly tms(poly a, poly b) {
        poly res(sz(a) + sz(b) - 1);
        for (int i = 0; i < sz(a); i++)
        for (int j = 0; j < sz(b); j++)
            res[i + j] = add(res[i + j], mul(a[i], b[j]));
        return res;
    }
}using namespace Poly;
int main() {
    #ifdef LOCAL
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
    #endif
    n = read(); k = read();
    ans = 1;
    for (int i = 1; i <= n; i++) ans = mul(ans, a[i] = read());
    f.pb(1);
    for (int i = 1; i <= n; i++) {
        vector<int> cur(2);
        cur[0] = a[i]; cur[1] = cmd - 1;
        f = tms(f, cur);
    }
    int dnm = 1, invnk = fpow(fpow(n, k), cmd - 2);
    for (int i = 0; i < min(sz(f), k + 1); dnm = mul(dnm, k - i), i++)
        ans = sub(ans, mul(mul(mul(fpow(n, k - i), dnm), f[i]), invnk));
    printf("%d", ans);
    return 0;
}
posted @ 2021-12-21 10:28  klii  阅读(44)  评论(0)    收藏  举报