组合数公式:
通项:
$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; }