HDU 5768 - Lucky7

题意:

    给出x, y, m[1...n], a[1..n].
      

    在[x,y]中寻找 p % 7 = 0 且对任意(1<= i <=n) p % m[i] != a[i] 的数字的个数
    
分析:

    可用容斥定理,先在[x,y]找出所有7的倍数,再根据多个模线性方程连立,去掉所有不合法的
      

    因 m[1...n] 互质,故可直接使用中国剩余定理.
   

    并且需要在其中用 快速加法 防止超 long long

 

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 using namespace std;
 5 #define LL long long
 6 const int MAXN = 20;
 7 LL ExtGcd(LL a,LL b,LL &x,LL &y)
 8 {
 9     if (b == 0) {x = 1; y = 0; return a;} 
10     LL d = ExtGcd(b, a%b, y, x);
11     y -= a / b * x;
12     return d;
13 }
14 LL Mul(LL a,LL b,LL MOD)
15 {
16     a%=MOD; b%=MOD;
17     LL res = 0;
18     while(b)
19     {
20         if (b&1) res = (res + a) % MOD;
21         a <<= 1; if(a > MOD) a-=MOD;
22         b >>= 1;
23     }
24     return res;
25 }
26 void CRT(LL &ans,LL &M, LL a[],LL m[],int k) //X = a[i] ( mod m[i] )(m[i]两两互质)
27 {                                            //解为 X = ans + M * t (0 <= ans <= M)
28     M = 1, ans = 0;
29     LL x, y, Mi;
30     for (int i = 0; i < k; i++) M *= m[i];
31     for (int i = 0; i < k; i++)
32     {
33         Mi = M / m[i];
34         ExtGcd(m[i], Mi, x, y);
35         ans = (ans + Mul( Mul(y, Mi, M), a[i], M)) % M;
36     }
37     if(ans < 0) ans += M;
38 }
39 int t, n;
40 LL x, y;
41 LL m1[MAXN], a1[MAXN], m[MAXN], a[MAXN];
42 LL Cal(LL m,LL a)
43 {
44     LL x0 = x + m - a;
45     LL y0 = y + m - a;
46     return y0 / m - (x0 - 1) / m;//计算[x,y]中有多少p % m = a
47 }
48 int main()
49 {
50     scanf("%d", &t);
51     for(int tt = 1; tt <= t; tt++)
52     {
53         scanf("%d%lld%lld", &n, &x, &y);
54         for(int i = 0; i < n ; i++)
55             scanf("%lld%lld", &m1[i], &a1[i]);
56         int cnt = 0;
57         LL ans = Cal(7,0);//找出所有7的倍数
58         for (int i = 1; i < (1<<n); i++)//枚举
59         {
60             cnt = 0;
61             for (int j = 0; j < n; j++)
62             {
63                 if (i & (1<<j))
64                 {
65                     m[cnt] = m1[j];
66                     a[cnt] = a1[j];
67                     ++cnt;
68                 }
69             }
70             m[cnt] = 7;
71             a[cnt] = 0;
72             ++cnt;
73             LL M,A;
74             CRT(A, M, a, m, cnt);
75             if (cnt%2) ans += Cal(M, A);//加奇数个,减偶数个 
76             else ans -= Cal(M, A); 
77         }
78         printf("Case #%d: %lld\n",tt,ans);
79     }
80 } 

 

posted @ 2016-07-30 23:46  nicetomeetu  阅读(186)  评论(0编辑  收藏  举报