HDU 4135 Co-prime(容斥原理)

题目链接

算是裸裸的模版题了,求a - b上 和 n互质的数,可是做的很费劲啊,有个地方没用__int64,让我DEBUG了好久。。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <map>
 5 using namespace std;
 6 #define ll __int64
 7 #define N 35000
 8 int o[N],prim[10000],num;
 9 ll judge(ll x, ll n)
10 {
11     int i,j,len;
12     int key[1001];
13     len = 0;
14     for(i = 1;i <= num-1;i ++)//这里也可以放到主函数里,重复算了。
15     {
16         if(n%prim[i] == 0)
17         {
18             key[len++] = prim[i];
19             while(n%prim[i] == 0)
20             n = n/prim[i];
21         }
22         if(n == 1) break;
23     }
24     if(n != 1) key[len++] = n;
25     int q;
26     ll sum,ans = 0;
27     for(i = 1;i < 1<<len;i ++)//状态压缩
28     {
29         q = 0;
30         sum = 1;
31         for(j = 0;j <= len-1;j ++)
32         {
33             if(i&(1<<j))
34             {
35                 sum *= key[j];
36                 q ++;
37             }
38         }
39         if(q&1)//奇数加偶数减
40         ans += x/sum;
41         else
42         ans -= x/sum;
43     }
44     return ans;
45 }
46 int main()
47 {
48     int i,j,len;
49     ll a,b,n;
50     len = (int)sqrt(N*1.0);
51     for(i = 2; i <= len; i ++)
52     {
53         if(!o[i])
54         {
55             for(j = i+i; j <= N; j += i)
56             {
57                 o[j] = 1;
58             }
59         }
60     }
61     num = 1;
62     for(i = 2;i <= N;i ++)
63     {
64         if(!o[i])
65         prim[num++] = i;
66     }
67     int t;
68     scanf("%d",&t);
69     for(i = 1;i <= t;i ++)
70     {
71         scanf("%I64d%I64d%I64d",&a,&b,&n);
72         printf("Case #%d: ",i);
73         printf("%I64d\n",(b-judge(b,n))-(a-1-judge(a-1,n)));
74     }
75     return 0;
76 }
posted @ 2012-10-04 13:43  Naix_x  阅读(154)  评论(0编辑  收藏  举报