计算 C(n,m)%p; 这边p是质数 如果不是质数就要麻烦一点
具体的证明不会 只能用那个公式
#include<stdio.h> #include<algorithm> #include<stdlib.h> #include<cstring> #include<string> #include<cmath> #include<vector> #include<queue> #include<map> #include<iterator> #include<stack> using namespace std; #define ll __int64 #define MAXN 500010 #define inf 2000000007 #define mod 1000000007 ll Quick(ll a,ll b,ll c) //快速幂 { ll ans=1; a=a%c; while(b>0) { if(b&1) ans = (ans*a)%c; b>>=1; a=(a*a)%c; } return ans; } ll calc(ll a,ll b,ll c) 这边计算比较小的组合数取mod 如果数组能存下 或者预处理出来每个数的阶乘都能优化一下 只要能算出来就行 { if(a<b) return 0; if(a==b) return 1; if(b>a-b) b=a-b; ll ca,cb; ca=cb=1; for(int i=0;i<b;i++) { ca=(ca*(a-i))%c; cb=(cb*(b-i))%c; } ll ans = (ca*Quick(cb,c-2,c))%c; //除法取mod 显然要乘逆元 c是质数的话就能用费马小定理求逆元了 return ans; } ll lucas(ll n,ll m,ll c) { ll ans=1; while(n&&m&&ans) { ans=(ans*calc(n%c,m%c,c))%c; n/=c; m/=c; } return ans; } int main() { ll n,m,p; while(scanf("%I64d%I64d%I64d",&n,&m,&p)!=EOF) { printf("%I64d ",lucas(n,m,p)); } return 0; }