RT,在 P6078 这道题里,需要快速计算 (mn),而其中 m 最大只可能是 10,所以我就想用 (mn)=m!n(n−1)⋯(n−m+1) 然后上下约分来计算,但是为什么只有 51 分呢?
代码:
#include <cstdio>
using namespace std;
typedef long long ll;
const ll mod = 2004;
ll n;
ll m[10];
ll ans;
void fix(ll & a) {
a = (a % mod + mod) % mod;
}
ll fm[10];
ll C(ll n, ll m) {
// m 一定是题目中给的 n
// 考虑约分计算
for (ll i = 0; i < m; i++) {
fm[i] = n - i;
}
for (ll i = m; i >= 1; i--) {
for (ll j = 0; j < m; j++) {
if (fm[j] % i == 0) {
fm[j] /= i;
break;
}
}
}
ll ans = 1;
for (int i = 0; i < m; i++) {
ans = ans * fm[i] % mod;
}
return ans;
}
void dfs(ll i, ll v, ll c, ll lim) {
if (c > lim) {
return;
} else if (i == n) {
ans = ans + v * C(n + lim - c, n);
fix(ans);
} else {
dfs(i + 1, v, c, lim);
dfs(i + 1, -v, c + m[i] + 1, lim);
}
}
ll solve(ll k) {
ans = 0;
dfs(0, 1, 0, k);
return ans;
}
int main() {
ll a, b;
scanf("%lld %lld %lld", &n, &a, &b);
for (ll i = 0; i < n; i++) {
scanf("%lld", m + i);
}
ll ans = solve(b) - solve(a - 1);
fix(ans);
printf("%lld", ans);
return 0;
}