Lucas定理
用来求 C(n,m) mod p,p为素数的值。
计算组合数取模,适用于n很大p较小的时候,可以将计算简化到小于p
公式:
例题:
题目背景 这是一道模板题。 题目描述 给定n,m,p(1<=n,m,p<=10^5) 求C[n+m,m]%P 保证P为质数 C表示组合数。 一个测试点内包含多组数据。 输入输出格式 输入格式: 第一行一个整数T(T≤10 ),表示数据组数 第二行开始共T行,每行三个数n m p,意义如上 输出格式: 共T行,每行一个整数表示答案。 输入输出样例 输入样例#1: 2 1 2 5 2 1 5 输出样例#1: 3 3
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const ll N=1e5+10; 5 ll n,m,p,T; 6 ll fc[N],inv[N]; 7 ll C(ll n,ll m) 8 { 9 if(n<m) return 0; 10 return fc[n]*inv[fc[m]%p]%p*inv[fc[n-m]]%p; 11 } 12 ll Lucas(ll n,ll m) 13 { 14 if(n<m) return 0; 15 ll ans=1; 16 for(;m;m/=p,n/=p) ans=ans*C(n%p,m%p)%p; 17 return ans; 18 } 19 int main() 20 { 21 scanf("%lld",&T); 22 while(T--) 23 { 24 scanf("%lld%lld%lld",&n,&m,&p); 25 fc[0]=1;inv[1]=1; 26 for(ll i=1;i<=n+m;++i) fc[i]=fc[i-1]*i%p; 27 for(ll i=2;i<=p;++i) inv[i]=(p-p/i)*inv[p%i]%p; 28 printf("%lld ",Lucas(n+m,m)); 29 } 30 return 0; 31 }