HDU 5446 Unknown Treasure (卢卡斯+CRT

代码:

 1 #include"bits/stdc++.h"
 2 #define db double
 3 #define ll long long
 4 #define vec vector<ll>
 5 #define Mt  vector<vec>
 6 #define ci(x) scanf("%d",&x)
 7 #define cd(x) scanf("%lf",&x)
 8 #define cl(x) scanf("%lld",&x)
 9 #define pi(x) printf("%d\n",x)
10 #define pd(x) printf("%f\n",x)
11 #define pl(x) printf("%lld\n",x)
12 const int N   = 1e5+5;
13 using namespace std;
14 typedef pair<ll, ll> pll;
15 ll F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
16 ll mul(ll a, ll b, ll mod) {
17     ll ret = 0;
18     while(b) {
19         if(b & 1)    ret = (ret + a) % mod;
20         a = (a + a) % mod;
21         b >>= 1;
22     }
23     return ret;
24 }
25 void init(int mod){
26     inv[1] = 1;
27     for(int i = 2; i < N; i ++){
28         inv[i] = (mod - mod / i) * 1ll * inv[mod % i] % mod;
29     }
30     F[0] = Finv[0] = 1;
31     for(int i = 1; i < N; i ++){
32         F[i] = F[i-1] * 1ll * i % mod;
33         Finv[i] = Finv[i-1] * 1ll* inv[i] % mod;
34     }
35 }
36 ll C(ll n, ll m,int mod){    //C(n, m)就是C(n, m)
37     if(m < 0 || m > n)  return 0;
38     return F[n] * 1ll * Finv[n - m] % mod * Finv[m] % mod;
39 }
40 ll Lucas(ll n, ll m, int p){
41     return m ? mul(Lucas(n/p, m/p, p),C(n%p, m%p, p),p) : 1;
42 }
43 ll exgcd(ll a, ll b, ll &x, ll &y)//ax+by=gcd(a,b)的整数解
44 {
45     ll d;
46     //if (a == 0 && b == 0) return -1;
47     if (b == 0)
48     {
49         x = 1,y = 0;
50         return a;
51     }
52     d = exgcd(b, a%b, y, x);
53     y -= a / b * x;
54     return d;
55 }
56 ll INV(ll a,ll p)
57 {
58     ll d,x,y;
59     d = exgcd(a,p,x,y);
60     return d==1?(x%p+p)%p:-1;
61 }
62 
63 ll china(int n, ll *a, ll *m){
64     ll M = 1, ret = 0;
65     for(int i = 0; i < n; i ++) M *= m[i];
66     for(int i = 0; i < n; i ++){
67         ll w = M / m[i];
68         ret = (ret + mul(mul(w, INV(w, m[i]),M),a[i],M)) % M;
69     }
70     return (ret + M) % M;
71 }
72 ll n,m;
73 int k;
74 ll P[N],R[N];
75 int main(){
76     int T;
77     scanf("%d",&T);
78     while(T--){
79         scanf("%lld%lld%d",&n,&m,&k);
80         for(int i=0;i<k;i++){
81            cl(P[i]);
82            init((int)P[i]);
83            R[i]=Lucas(n,m,P[i]);
84         }
85         ll ans=china(k,R,P);
86         pl(ans);
87     }
88     return 0;
89 }

 

posted @ 2018-08-08 09:16  thges  阅读(135)  评论(0编辑  收藏  举报