Lucas定理
卢卡斯定理
卢卡斯定理
卢卡斯定理是求
证明
实现
组合操作:
int c(int m,int n,int p){
if (n<m) return 0;//上面比下面大,当然输出0
if (m>=p || n>=p) return c(m/p,n/p,c)*c(m%p,n%p,p);//公式的直接调用
if (m==0 || n==0) return 1;//有一个是0,就输出1
return fact[n]*invfact[m]%p*invfact[n-m]%p;
}
最后一句话的意思是:
fact[0]=fact[1]=1;
for (int i=2;i<=p;i++) fact[i]=fact[i-1]*i%p;
就这样完成了!
求C(m,n,p)即可。
完整代码
P3807模板题
注意,这道模板题求的是
#include <bits/stdc++.h>
#define N 100001
using namespace std;
#define LL long long
LL f[N],inv[N];
inline LL C(int m,int n,int p) {
if (n<m) return 0;
if (m>=p || n>=p) return C(m/p,n/p,p)*C(m%p,n%p,p)%p;
if (m==0 || n==0) return 1;
return f[n]*inv[m]%p*inv[n-m]%p;
}
int main(){
int T;
scanf("%d",&T);
while (T--){
int m,n,p;
scanf("%d %d %d",&n,&m,&p);
n+=m;f[0]=inv[0]=f[1]=inv[1]=1;
for (int i=2;i<=p;i++) f[i]=f[i-1]*i%p;
for (int i=2;i<=p;i++) inv[i]=(p-p/i)*inv[p%i]%p;
for (int i=2;i<=p;i++) inv[i]=inv[i-1]*inv[i]%p;
printf("%lld\n",C(m,n,p));
}
return 0;
}