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 }
View Code

题目链接:无2333

posted on 2015-04-13 16:11  xiao_xin  阅读(225)  评论(0编辑  收藏  举报

导航