【莫比乌斯反演】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 }