求 C(n+m, m) mod p,其中 n, m ≤ 10^18,p 為質數。直接計算階乘不可行,需用 Lucas 定理分解。
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
LL mod_pow(LL a, LL n, LL p) {
LL res = 1;
while (n) {
if (n & 1) res = res * a % p;
a = a * a % p;
n >>= 1;
}
return res;
}
LL C(LL n, LL m, LL p) {
if (m > n) return 0;
LL num = 1, den = 1;
for (LL i = 0; i < m; i++) {
num = num * (n - i) % p;
den = den * (m - i) % p;
}
return num * mod_pow(den, p - 2, p) % p;
}
LL Lucas(LL n, LL m, LL p) {
if (m == 0) return 1;
return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
LL n, m, p; scanf("%lld%lld%lld", &n, &m, &p);
printf("%lld\n", Lucas(n + m, m, p));
}
return 0;
}
__int64 或 long long 防止溢位,中間乘法取模。