[CEOI2004] Sweets
Statement
Solution
考虑对每堆构造其生成函数:
\[F_i(x)=\sum\limits_{j=0}^{m_i}x^j
\]
\[xF_i(x)+1-x^{m_i+1}=F_i(x)
\]
\[F_i(x)=\dfrac{1-x^{m_i+1}}{1-x}
\]
总共取\(i\)个的生成函数就是;
\[G(x)=\prod\limits_{i=1}^nF_i(x)=(1-x)^{-n}\prod\limits_{i=1}^n(1-x^{m_i+1})
\]
答案即为:
\[\sum\limits_{i=a}^b[x^i]G(x)
\]
根据牛顿二项式定理可知:
\[(1-x)^{-n}=\sum\limits_{i=0}^n\dbinom{-n}{i}(-x)^i=\sum\limits_{i=0}^n\dfrac{(-n)^{\underline{i}}}{i!}(-x)^i=\sum\limits_{i=0}^n\dbinom{n+i-1}{i}x^i
\]
因此
\[G(x)=\left[\sum\limits_{i=0}^n\dbinom{n+i-1}{i}x^i\right]\cdot\prod_{i=1}^n(1-x^{m_i+1})
\]
因为\(n\leq10\),所以可以对\(\prod(1-x^{m_i+1})\)暴力展开,求得\(x^k\)的系数为\(c_k\)。考虑每个\(k\)对答案的贡献:
\[c_k\sum\limits_{i=a-k}^{b-k}\dbinom{n+i-1}{i}=c^k\sum\limits_{i=a-k}^{b-k}\left[\dbinom{n+i}{i}-\dbinom{n+i-1}{i-1}\right]
\]
\[=c^k\left[\dbinom{n+b-k}{b-k}-\dbinom{n+a-k-1}{a-k-1}\right]=c^k\left[\dbinom{n+b-k}{n}-\dbinom{n+a-k-1}{n}\right]
\]
时间复杂度为\(\mathcal O(n2^n)\)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 15;
const unsigned int P = 2004;
int A[MAXN];
int n, limL, limR, fac = 1, ans;
inline int binom(int a, int b) {
if (a < b)
return 0;
static const unsigned long long MOD = 1ll * P * fac;
long long res = 1;
for (int i = a - b + 1;i <= a; ++i)
res = res * i % MOD;
return (res / fac) % P;
}
void getAns(int id, int o, int k) {
if (id == n + 1)
return ans = (1ll * ans + (o * (binom(n + limR - k, n) - binom(n + limL - k - 1, n)) + P) % P + P) % P, void();
getAns(id + 1, o, k), getAns(id + 1, -o, k + 1 + A[id]);
}
int main(void) {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> limL >> limR;
for (int i = 1;i <= n; ++i)
cin >> A[i], fac *= i;
getAns(1, 1, 0),
cout << ans << '\n';
return 0;
}

浙公网安备 33010602011771号