【莫比乌斯反演】HDU1695_GCD

唔第一道莫比乌斯反演,公式推了一整个上午..

 

 

【错误】

计算ans的时候一定要把int强制转换为long long?我还不是很明白原因。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 const int MAXN=100000+50;
 8 const int INF=0x7fffffff;
 9 int a,b,c,d,inp,ub;
10 int miu[MAXN];
11 
12 void init()
13 {
14     scanf("%d%d%d%d%d",&a,&b,&c,&d,&inp);
15     if (inp!=0)
16     {
17         b=b/inp;
18         d=d/inp;
19         ub=min(b,d);
20     }
21 }
22 
23 void get_miu(int maxn)
24 {
25     int prime[MAXN],pnum=0;
26     miu[1]=1;
27     for (int i=2;i<maxn;i++) miu[i]=-INF;
28     for (int i=2;i<maxn;i++)
29     {
30         if (miu[i]==-INF)
31         {
32             miu[i]=-1;
33             prime[++pnum]=i;
34         }
35         for (int j=1;j<=pnum;j++)
36         {
37             if (i*prime[j]>=maxn) break;
38             if (i%prime[j]==0) miu[i*prime[j]]=0;
39                 else miu[i*prime[j]]=-miu[i];
40         }
41     }
42 }
43 
44 ll get_ans()
45 {
46     ll ans1=0,ans2=0;
47     for (int k=1;k<=ub;k++)
48       ans1+=(ll)miu[k]*(b/k)*(d/k);
49     for (int k=1;k<=ub;k++)
50       ans2+=(ll)miu[k]*(ub/k)*(ub/k);//这里一定要写成(ll) 
51     ll ans=ans1-ans2/2;
52     return (ans);
53 }
54 
55 int main()
56 {
57     int T;
58     scanf("%d",&T);
59     get_miu(MAXN);
60     for (int i=0;i<T;i++)
61     {
62         cout<<"Case "<<i+1<<": ";
63         init();
64         if (inp==0)
65         {
66             cout<<0<<endl;continue;
67         }
68         cout<<get_ans()<<endl;
69     }
70     return 0;
71 }

 

posted @ 2016-07-02 14:16  iiyiyi  阅读(1135)  评论(0编辑  收藏  举报