标签:int desc can getch pre 解释 合数 init ons
求 \(\sum_{i=x1}^{x2}\sum_{j=y1}^{y2}C[i][j]\%p\)。
组合数有一个式子:\(C[i][j]=C[i-1][j-1]+C[i-1][j]\)。
我们可以这样理解一下这个式子:这是一个前缀和,如果我们先枚举 j 再枚举 i,那么其实这个数组相当于每次加上一个与这一轮无关紧要的数。
而我们这道题迫切需要的就是前缀和的优化。
可以得出:
解释一下:\(C[x1][j+1]\) 就是 \(\sum_{i=1}^{x1-1}C[i][j]\)。前者同理。
#include <cstdio>
typedef long long ll;
ll p, fac[100005];
int read() {
int x = 0, f = 1; char s;
while((s = getchar()) > ‘9‘ || s < ‘0‘) if(s == ‘-‘) f = -1;
while(s <= ‘9‘ && s >= ‘0‘) {
x = (x << 1) + (x << 3) + (s ^ 48);
s = getchar();
}
return x * f;
}
ll qkpow(ll x, ll y) {
ll r = 1;
while(y) {
if(y & 1) r = r * x % p;
x = x * x % p; y >>= 1;
}
return r;
}
ll C(const int n, const int m) {
if(n < m) return 0;
return fac[n] * qkpow(fac[m] * fac[n - m] % p, p - 2) % p;
}
ll Lucas(const int n, const int m) {
if(n < m) return 0;
if(! m) return 1;
return Lucas(n / p, m / p) * C(n % p, m % p) % p;
}
void init() {
fac[0] = 1;
for(int i = 1; i <= 100000; ++ i) fac[i] = fac[i - 1] * i % p;
}
int main() {
int x1, x2, y1, y2; ll ans;
while(~ scanf("%d %d %d %d %lld", &x1, &y1, &x2, &y2, &p)) {
ans = 0; init();
for(int i = y1; i <= y2; ++ i) ans = (ans + Lucas(x2 + 1, i + 1) - Lucas(x1, i + 1) + p) % p;
printf("%lld\n", ans);
}
return 0;
}
标签:int desc can getch pre 解释 合数 init ons
原文地址:https://www.cnblogs.com/AWhiteWall/p/12752596.html