卢卡斯定理模板
题目来源:P3807 【模板】卢卡斯定理/Lucas 定理
有了以上前提之后就可以编写代码了
不难看出,根据公式来写题需要用到:
1.快速幂
2.费马小定理求逆
3.递归
可能有人对费马小定理求逆这块儿有疑惑,简单说明一下
对于素数p,有
a ^ (p-1) = a ^ (p-2) * a
所以a的逆元是a^(p-2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int const maxn=100001;
ll fac[maxn],inv[maxn];
ll fast_pow(ll x,ll y,ll mod){
ll ans=1;
x%=mod;
while(y){
if(y&1) ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans;
}
ll inverse(ll n,ll mod){return fast_pow(fac[n],mod-2,mod);}
ll c(ll n,ll m,ll mod){
if(m>n) return 0;
return (fac[n]*inverse(m,mod)%mod * inverse(n-m,mod)%mod)%mod;
}
ll Lucas(ll n,ll m,ll mod){
if(m==0) return 1;
return c(n%mod,m%mod,mod)*Lucas(n/mod,m/mod,mod)%mod;
}
int main(void){
fac[0]=1;
int T;cin>>T;
while(T--){
int n,m,p;
cin>>n>>m>>p;
for(int i=1;i<=n+m;++i) fac[i]=(fac[i-1]*i)%p;
cout<<Lucas(n+m,n,p)<<endl;
}
return 0;
}
注意开longlong就完事了