(mathcal{Description})
Link.
给定非负整数序列 ({a_n}),设 ({b_n}) 是一个非负整数序列且 (sum_{i=1}^nb_ile m),求
[sum_{{b_n}}prod_{i=1}^ninom{b_i}{a_i}mod(10^9+7)
]
(n,a_ile2 imes10^3)。
(mathcal{Solution})
鉴于这是 ARC D,可以直观感受到是一个代码不长的组合意义题。(
考虑一个 (prod_{i=1}^ninom{b_i}{a_i}) 的意义:
有 (m) 个球排成一行,将其分成 (n+1) 段,第 (i~(ile n)) 段长度 (b_i),再从这些段内选 (a_i) 个球。
那么对其求和,意义即为:
有 (m) 个球排成一行,将其任意分成 (n+1) 段,再从前 (n) 段内每段选 (a_i) 个球。
把“分段”当成球,所以:
有 (m+n) 个球排成一行,先选 (a_1) 个球,再选 (1) 个球,接着选 (a_2) 个球,再选 (1) 个球……
进一步:
有 (m+n) 个球排成一行,选 (n+sum_{i=1}^na_i) 个球。
故答案为 (inom{n+m}{n+sum_{i=1}^na_i})。复杂度 (mathcal O(sum_{i=1}^na_i))。
(mathcal{Code})
/* Clearink */
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, rpbound##i = r; i <= rpbound##i; ++i )
#define per( i, r, l ) for ( int i = r, rpbound##i = l; i >= rpbound##i; --i )
const int MOD = 1e9 + 7, MAXN = 2e3;
int n, m, fac[MAXN + 5], inv[MAXN * MAXN + 5];
inline int mul ( const long long a, const int b ) { return a * b % MOD; }
inline void init ( const int n ) {
inv[1] = 1;
rep ( i, 2, n ) inv[i] = mul ( inv[MOD % i], MOD - MOD / i );
}
inline int comb ( const int n, const int m ) {
if ( n < m ) return 0;
int ret = 1;
for ( int i = 1; i <= m; ++i ) ret = mul ( ret, mul ( n - i + 1, inv[i] ) );
return ret;
}
int main () {
scanf ( "%d %d", &n, &m );
int s = 0;
for ( int i = 1, a; i <= n; ++i ) {
scanf ( "%d", &a );
s += a;
}
init ( s + n );
printf ( "%d
", comb ( n + m, s + n ) );
return 0;
}