题解 | #一道计数题#

一道计数题

https://ac.nowcoder.com/acm/contest/30896/J

题目实际上是在求:

k=0m[xk]i=1ni=0(iai)xi\sum_{k=0}^{m}[x^k]\prod_{i=1}^{n}\sum_{i=0}^{\infty}\binom{i}{a_i}x^{i}

由常见生成函数式子可知:

1(1x)p=i=0(i+p1p1)xi\frac{1}{(1-x)^p}=\sum_{i=0}^{\infty}\binom{i+p-1}{p-1}x^i

p=ai+1p=a_i+1 可得:

k=0m[xk]i=1ni=0(iai)xi=k=0m[xk]i=1nxai(1x)ai+1=k=0m[xk]xi=1nai(1x)n+i=1nai\begin{aligned} \sum_{k=0}^{m}[x^k]\prod_{i=1}^{n}\sum_{i=0}^{\infty}\binom{i}{a_i}x^i&=\sum_{k=0}^{m}[x^k]\prod_{i=1}^{n}\frac{x^{a_i}}{(1-x)^{a_i+1}}\\ &=\sum_{k=0}^{m}[x^k]\frac{x^{\sum_{i=1}^{n} a_i}}{(1-x)^{n+\sum_{i=1}^{n}a_i}} \end{aligned}

t=i=1nait=\sum_{i=1}^n a_i,所以可以推出最后所求为,再通过组合数斜线求和公式可得:

k=0m(k+n1n+t1)=(m+nn+t)\sum_{k=0}^{m}\binom{k+n-1}{n+t-1}=\binom{m+n}{n+t}

所以 O(n+t)O(n+t) 求一个组合数即可。

#include<bits/stdc++.h>

using namespace std;

const int MOD = 1e9 + 7;

int mpow(int x , int y = MOD - 2) {
    int ret = 1;
    while (y) {
        if (y & 1) ret = 1ll * ret * x % MOD;
        x = 1ll * x * x % MOD;
        y >>= 1;
    }
    return ret;
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(0);

    int N , m;
    cin >> N >> m;

    int u = m + N;

    int sum = 0;
    for (int i = 1 ; i <= N ; i++) {
        int x;
        cin >> x;
        sum += x;
        if (sum >= MOD) sum -= MOD;
    }

    if (m + N < N + sum) {
        cout << "0\n";
    } else {
        int ans = 1 , d = 1;
        for (int i = 1 ; i <= N + sum ; i++) {
            ans = 1ll * ans * (u - i + 1) % MOD;
            d = 1ll * d * i % MOD;
        }
        d = mpow(d);
        cout << 1ll * ans * d % MOD << endl;
    }
    return 0;
}
全部评论
这题其实打表,打个三项就出来了哈哈
点赞 回复 分享
发布于 2022-03-27 12:55
请问题目实际上是在求的这个式子是怎么得出来的?
点赞 回复 分享
发布于 2022-03-27 15:15

相关推荐

7 收藏 评论
分享
牛客网
牛客企业服务