大组合数取膜(非质数)

模板

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 
 5 using namespace std;
 6 typedef long long LL;
 7 const int N = 200005;
 8 
 9 bool prime[N];
10 int p[N];
11 int cnt;
12 
13 void isprime()
14 {
15     cnt = 0;
16     memset(prime,true,sizeof(prime));
17     for(int i=2; i<N; i++)
18     {
19         if(prime[i])
20         {
21             p[cnt++] = i;
22             for(int j=i+i; j<N; j+=i)
23                 prime[j] = false;
24         }
25     }
26 }
27 
28 LL quick_mod(LL a,LL b,LL m)
29 {
30     LL ans = 1;
31     a %= m;
32     while(b)
33     {
34         if(b & 1)
35         {
36             ans = ans * a % m;
37             b--;
38         }
39         b >>= 1;
40         a = a * a % m;
41     }
42     return ans;
43 }
44 
45 LL Work(LL n,LL p)
46 {
47     LL ans = 0;
48     while(n)
49     {
50         ans += n / p;
51         n /= p;
52     }
53     return ans;
54 }
55 
56 LL Solve(LL n,LL m,LL P)
57 {
58     LL ans = 1;
59     for(int i=0; i<cnt && p[i]<=n; i++)
60     {
61         LL x = Work(n, p[i]);
62         LL y = Work(n - m, p[i]);
63         LL z = Work(m, p[i]);
64         x -= (y + z);
65         ans *= quick_mod(p[i],x,P);
66         ans %= P;
67     }
68     return ans;
69 }
70 
71 int main()
72 {
73     int T;
74     isprime();
75     cin>>T;
76     while(T--)
77     {
78         LL n,m,P;
79         cin>>n>>m>>P;
80         n += m - 2;
81         m--;
82         cout<<Solve(n,m,P)<<endl;
83     }
84     return 0;
85 }

 

posted @ 2017-08-04 16:33  yZi  阅读(243)  评论(0编辑  收藏  举报