C(n,m)%p n,m<=10^5,p<=10^9 p非质数
(a/b) mod m:
gcd(b,m) = 1
求b相对m的逆元b^(-1),即b*(b^(-1))= 1 (mod m),然后计算a*b^(-1) mod m,其值与(a/b) mod m相同
gcd(b,m)!=1
不可以用逆元了,倒可以把a/b分解质因数相乘,然后快速幂,将除法取模转化为乘法取模(似乎可以将p的质因子处理一下来处理n和m?这样确实有些慢了,先写这个吧==
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define LL long long 6 LL count(LL n,LL p) 7 { 8 LL ans=0; 9 while (n/p) 10 { 11 ans+=n/p; 12 n=n/p; 13 } 14 return ans; 15 } 16 LL quick(LL a,LL b,LL mod) 17 { 18 LL ans=1; 19 while (b){ 20 if (b%2) ans=ans*a%mod; 21 a=a*a; 22 b/=2; 23 } 24 return ans; 25 } 26 LL vis[200005],prime[200005]; 27 int main() 28 { 29 LL cnt=0,i,j,n,mod,m,tmp,ans; 30 memset(vis,0,sizeof(vis)); 31 for (i=2;i<=200000;i++) 32 if (vis[i]==0){ 33 prime[++cnt]=i; 34 for (j=2;i*j<=200000;j++) vis[i*j]=1; 35 } 36 while (~scanf("%lld%lld%lld",&n,&m,&mod)) 37 { 38 ans=1; 39 for (i=1;i<=cnt&&prime[i]<=n;i++) 40 { 41 tmp=count(n,prime[i])-count(m,prime[i])-count(n-m,prime[i]); 42 ans=ans*quick(prime[i],tmp,mod)%mod; 43 if (!ans) break; 44 } 45 printf("%lld\n",ans); 46 } 47 }
题目链接:无2333