题目:给出n,求出有多少小于n的三元组(自然数),使得gcd(x, y, z)为1, 即从三维空间(0, 0, 0) 可以看到的点数。
莫比乌斯反演两种形式
证明:
此题用的是第二种,设f(m)为m | gcd(x, y, z)个数,g(m)为gcd(x, y, z) = m 的个数。因为f(x) = (n/x) ^ 3, 且f(x) = sigma{ x|d, g(d) }, 所以g(x) = sigma{ x|d, mu(d/x) * f(d) }. 算出g(1)即可。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#define Rep(i, x, y) for (int i = x; i <= y; i ++)
using namespace std;
typedef long long LL;
const int N = 1000005;
int n, pri[N], tot, mu[N], T;
bool c[N];
LL ans;
void Pre() {
mu[1] = 1;
Rep(i, 2, N-5) {
if (!c[i]) pri[++ tot] = i, mu[i] = -1;
Rep(j, 1, tot) {
if (i * pri[j] > N-5) break ;
c[i*pri[j]] = 1;
if (i % pri[j] == 0) {
mu[i*pri[j]] = 0;
break ;
}
mu[pri[j]*i] = -mu[i];
}
}
}
int main()
{
cin >> T;
Pre();
while (T --) {
scanf ("%d", &n), ans = 3;
for (int i = 1; i <= n; i ++) ans += LL(mu[i]) * (n/i) * (n/i) * (n/i+3);
printf("%lld\n", ans);
}
return 0;
}