标签:ace namespace cas int cin mod space str efi
Lucas定理是用来求 c(n,m) mod p,p为素数的值。
C(n,m)%p = C(n/p,m/p) * C(n%p,m%p)%p
\(Lucas(n,m,p)=C(n \% p,m \% p) \times Lucas(\frac{n}{p},\frac{m}{p},p)\)
\(\binom{n}{m}=\frac{n!}{m!(n-m)!}\)
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
ll pow(ll a,ll b,ll p){
ll ans = 1;
a%=p;
while(b){
if(b&1)ans = (ans%p)*(a%p)%p;
b>>=1;
a = a*a%p;
}
return ans;
}
ll inv(ll x,ll p){//x关于p的逆元,p为素数
return pow(x,p-2,p);
}
ll C(ll n,ll m,ll p){//求组合数C(n,m)%p
if(n<m)return 0;
ll up=1,down=1;//分子分母
for(ll i=n-m+1;i<=n;i++)up=up*i%p;
for(ll i=1;i<=m;i++)down=down*i%p;
return up*inv(down,p)%p;
}
ll lucas(ll n,ll m,ll p){
if(m==0)return 1;
return C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
int main(){
int t;
cin>>t;
ll n,m,p;
while(t--){
cin>>n>>m>>p;
cout<<lucas(n,m,p)<<endl;
}
return 0;
}
当p不为素数的时候
标签:ace namespace cas int cin mod space str efi
原文地址:https://www.cnblogs.com/Emcikem/p/11746942.html