题目描述 https://ac.nowcoder.com/acm/contest/30896/J
简要题意:给定一个长度为 $n$ 的序列 $a_i$,现在需要计算对于所有满足条件的序列 $b_i$ $\prod_{i=1}^n\binom{b_i}{a_i}$ 的累加和,序列 $b_i$ 满足的条件为序列 $b$ 只包含自然数且长度为 $n$,序列 $b_i$ 中所有数的和小于等于 $m$
$n\le 5000,a_i\le 2000,m\le 10^9$
Solution 考虑生成函数,我们令 $F_k(x)=\sum_{i=0}^\infty\binom{i}{a_k}x^k$,容易得到答案就是 $\sum_{k=0}^m[x^k]\prod_{i=1}^nF_i(x)$,注意到 $F_i(x)$ 的形式还可以继续化简,根据 $\frac{1}{(1-x)^k}=\sum_{i=0}^\infty\binom{i+k-1}{k-1}x^i$,我们可以得到 $F_k(x)=\frac{x^{a_k}}{(1-x)^{a_k+1}}$
那么 $ans=\sum_{k=0}^m[x^k]\frac{x^{\sum_{i=1}^na_i}}{(1-x)^{n+\sum_{i=1}^na_i}}$,我们令 $t=\sum_{i=1}^na_i$,那么 $ans=\binom{m+n}{n+t}$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <iostream> #define maxn 5010 #define ll long long using namespace std ;const int p = 1000000007 ;ll pow_mod (ll x, ll n) { ll s = 1 ; for (; n; n >>= 1 , x = x * x % p) if (n & 1 ) s = s * x % p; return s; } int n, m, a[maxn];int main () { ios::sync_with_stdio(false ); cin .tie(nullptr ); cout .tie(nullptr ); cin >> n >> m; int sum = 0 ; for (int i = 1 ; i <= n; ++i) cin >> a[i], sum += a[i]; if (sum > m) return cout << 0 << "\n" , 0 ; ll ans = 1 , mul = 1 ; for (int i = 1 ; i <= n + sum; ++i) { ans = ans * (m - sum + i) % p; mul = mul * i % p; } cout << ans * pow_mod(mul, p - 2) % p << "\n"; return 0 ; }