组合数公式:
通项:
$C(n,m) = n!/(m!*(n-m)!)$
递推:
$C(n,m) = C(n-1,m-1)+C(n-1,m)$
Lucas定理:
适用于p是质数,且p较小的情况
$Lucas(n,m) = Lucas(n/p,m/p) * C(n$ $mod$ $p,m$ $mod$ $p)$ $(mod$ $p)$
$Lucas(n,0) = 1$
代码如下
const int maxn = 1e5+10;
int t,n,m,p;
long long f[maxn];
void get_fac() {
f[0] = 1;
for(int i = 1; i <= p; i++)
f[i] = (f[i-1]*i) % p;
}
int qpow(int a,int b){
long long ans = 1,base = a;
while(b){
if(b&1) ans = (ans*base) % p;
base = (base*base) % p;
b >>= 1;
}
return ans;
}
int inv(int x){
return qpow(x,p-2);
}
int C(int n,int m){
if(m > n) return 0;
return f[n] * inv(f[m])%p * inv(f[n-m])%p;
}
int lucas(int n,int m){
if(m == 0) return 1;
return (long long)lucas(n/p,m/p) * C(n%p,m%p) % p;
}
int main() {
scanf("%d",&t);
while(t--) {
scanf("%d%d%d",&n,&m,&p);
get_fac();
printf("%d\n",lucas(n+m,m));
}
return 0;
}