组合数学(费马小定理+卢卡斯定理)模板
作者:互联网
组合数取模(费马小定理)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int G = 1000000;
#define mod 1000000007
ll pri[G];
ll ni[G];
ll pow(ll a,ll b,ll m){
ll ans = 1;
a %= m;
while(b){
if(b&1)ans=(ans%m)*(a%m)%m;
b /= 2;
a = (a%m)*(a%m)%m;
}
ans %= m;
return ans;
}
int main(){
pri[0]=1;
ni[0]=1;
for(int i=1;i<G;i++){
pri[i]=pri[i-1]*i%mod;
ni[i]=pow(pri[i],mod-2,mod);
}
int n,b;
while(cin>>n>>b){
ll ans=((pri[n]*ni[b]%mod)*ni[n-b])%mod;
printf("%lld\n",ans);
}
}
组合数取模(卢卡斯定理)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
ll n,m,p,fac[maxn];
ll pow(ll x,ll k){
ll ans = 1;
while(k){
if(k&1) ans=ans*x%p;
k>>=1;
x=x*x%p;
}
return ans;
}
ll C(ll k,ll b){
if(k<b) return 0;
return fac[k]*pow(fac[b]%p,p-2)%p*pow(fac[k-b]%p,p-2)%p;
}
ll Lucas(ll k,ll b){
if(!b) return 1;
return C(k%p,b%p)*Lucas(k/p,b/p)%p;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
fac[0]=1;
scanf("%lld%lld%lld",&n,&m,&p);
for(int i=1;i<=p;++i){
fac[i]=fac[i-1]*i%p;
}
printf("%lld\n",Lucas(n,m));
}
return 0;
}
标签:ni,费马,int,定理,pri,long,ans,卢卡斯,ll 来源: https://blog.csdn.net/jiangkun0331/article/details/99709549