1 /***
2 大意:计算gcd(x,y,z) =1 0<= x, y , z <= n 问有多少个这样的对
3 莫比乌斯反演:(反演: 用结果推原因)
4 函数m(m)的定义如下:
5

6
7 莫比乌斯反演:
8
9 * f(x) = sigma{g(d)}其中x % d == 0,则g(x) = sigma{miu(d) * f(x/d)}
10 * f(x) = sigma{g(d)}其中d % x == 0,则g(x) = sigma{miu(d/x) * f(d)}
11
12 莫比乌斯反演中miu(x) =
13
14 * 1 {x中含有偶数个不同的质因子}
15 * -1 {x中含有奇数个不同的质因子}
16 * 0 {其他情况}
17
18 本题: 设f(x) = 约数为x 的所有数集合 g(x) = 最大公约数gcd 为x的集合
19 那么g(x) = siga(mu(d)*f(x/d)) x%d==0
20 或者 g(x) = siga(mu(d/x) *f(d)) d%x==0
21
22 在本题中只包含了x,y,z>1 情况 ,,还应加上退化到3个平面上的情况。。
23 1、 f(x) = n/x*n/x*n/x;----〉 g(x) = mu[i] *(n/x*n/x*n/x)
24 2、 加上退化到三个平面 ----〉 g(x) = mu[i]*(n/x+1)*(n/x+1)*(n/x+1)
25
26 或者分开求:
27 1、 三个坐标轴。。3
28 2、 空间中 n/x* n/x*n/x;
29 3、 三个坐标平面: n/x*n/x +n/x*n/x +n/x*n/x
30 **/
31 1、 第一种方法
32 #include <iostream>
33 #include <cstring>
34 using namespace std;
35
36 const int maxn = 1000050;
37 int pri[maxn];
38 int prime[maxn];
39 int mu[maxn];
40
41 void pri_mu(){
42 memset(prime,0,sizeof(prime));
43 int cnt =0;
44 mu[1] =1;
45 for(int i=2;i<maxn;i++){
46 if(!prime[i]){
47 mu[i] =-1;
48 pri[cnt++] = i;
49 }
50 for(int j=0;j<cnt;j++){
51 if(i*pri[j]>maxn)
52 break;
53 prime[i*pri[j]] = 1;
54 if(i%pri[j]==0){
55 mu[i*pri[j]] =0;
56 break;
57 }else
58 mu[i*pri[j]] = -mu[i];
59 }
60 }
61 }
62
63 int main()
64 {
65 pri_mu();
66 int t;
67 cin>>t;
68 long long n;
69 while(t--){
70 cin>>n;
71 long long ans =0;
72 for(int i=1;i<=n;i++)
73 ans += (long long )mu[i]*((n/i+1)*(n/i+1)*(n/i+1)-1);
74 cout<<ans<<endl;
75 }
76 return 0;
77 }
78 ----------------------------------------------------------------------------------------------------------
2、 第二种方法
79 #include <iostream>
80 #include <cstring>
81 using namespace std;
82
83 const int maxn = 1000050;
84 int pri[maxn];
85 int prime[maxn];
86 int mu[maxn];
87
88 void pri_mu(){
89 memset(prime,0,sizeof(prime));
90 int cnt =0;
91 mu[1] =1;
92 for(int i=2;i<maxn;i++){
93 if(!prime[i]){
94 mu[i] =-1;
95 pri[cnt++] = i;
96 }
97 for(int j=0;j<cnt;j++){
98 if(i*pri[j]>maxn)
99 break;
100 prime[i*pri[j]] = 1;
101 if(i%pri[j]==0){
102 mu[i*pri[j]] =0;
103 break;
104 }else
105 mu[i*pri[j]] = -mu[i];
106 }
107 }
108 }
109
110 int main()
111 {
112 pri_mu();
113 int t;
114 cin>>t;
115 long long n;
116 while(t--){
117 cin>>n;
118 long long ans =3;
119 for(int i=1;i<=n;i++)
120 ans += (long long )mu[i]*((n/i)*(n/i)*(n/i+3));
121 cout<<ans<<endl;
122 }
123 return 0;
124 }