洛谷 #3807. 【模板】盧卡斯定理
阿新 • • 發佈:2018-11-24
題意
求C(n + m, m) % p,保證p為質數
題解
盧卡斯定理
對C(m, n),令
\(m = k_1 * p + r_1\)
\(n = k_2 * p + r_2\)
則 \(C(m, n) = C(k_1, k_2) * C(r_1, r_2)\)
除錯記錄
無
#include <cstdio>
#define maxn 200005
#define int long long
using namespace std;
int T, n, m, mo, fac[maxn], inv[maxn];
int C(int m, int n){
if (m < n) return 0;
if (n == 0 || n == m) return 1;
return fac[m] * inv[n] % mo * inv[m - n] % mo;
}
int Lucas(int m, int n){
if (m < n) return 0;
if (n == 0 || n == m) return 1;
if (n < mo && m < mo) return C(m, n);
return Lucas(m / mo, n / mo) * Lucas(m % mo, n % mo) % mo;
}
signed main(){
scanf("%lld", &T);
while (T--){
scanf("%lld%lld%lld", &n, &m, &mo);
fac[1] = 1; inv[1] = 1;
for (int i = 2; i <= n + m; i++) fac[i] = fac[i - 1] * i % mo;
for (int i = 2; i <= n + m; i++) inv[i] = (mo - mo / i) * inv[mo % i] % mo;
for (int i = 2; i <= n + m; i++) inv[i] = inv[i] * inv[i - 1] % mo;
printf("%lld\n", Lucas(n + m, m));
}
return 0;
}