题意
给出(n leq {10} ^ {12}),求
[sum_{a = 1} ^ n sum_{b = 1} ^ n sum_{c = 1} ^ n [frac{1}{a} + frac{1}{b} = frac{1}{c}] [gcd(a, b, c) = 1]
]
题解
[egin{aligned}
= & sum_{a = 1} ^ n sum_{b = 1} ^ n sum_{c = 1} ^ n [c(a + b) = ab] [(a, b, c) = 1] \
= & sum_{a = 1} ^ n sum_{b = 1} ^ n [(a + b) | ab] [(a, b, frac{ab}{a + b}) = 1] \
end{aligned}
]
设(g = (a, b)),则一对((a, b))合法的充要条件(a + b = g ^ 2)。
则原问题相当于求
[egin{aligned}
sum_{g = 1} ^ {sqrt {2n}} sum_i [(g ^ 2 - i g, i g) = g]
= & sum_{g = 1} ^ {sqrt {2n}} sum_i [(g, i) = 1] \
end{aligned}
]
考虑(i)的上下界
[1 leq i g leq n \
1 leq g ^ 2 - i g leq n \
]
得
[i in cap left[ max(g - lfloor frac{n}{g}
floor,1), min(lfloor frac{n}{g}
floor, g - 1)
ight]
]
即求
[sum_{g = 1} ^ {sqrt{2n}} sum_{i = ext{lowerbound}} ^ { ext{upperbound}} [(g, i) = 1]
]
考虑对后面的东西做前缀和是
[f(L) = sum_{i = 1} ^ L [(g, i) = 1]
]
反演一下可以得到
[f(L) = sum_{d | g} mu(d) lfloor frac{L}{d}
floor
]
则原式即求
[sum_{g = 1} ^ {sqrt {2n}} f( ext{upperbound}) - f( ext{lowerbound} - 1)
]
复杂度(mathcal O(sqrt n log n))。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 2e6 + 5, M = 4e7 + 5;
ll n, m, ans;
int p[N], mu[N], vis[N], d[M], tmp[N], cnt[N];
int calc (int g, int n) {
int ret = 0;
for (int i = cnt[g - 1] + 1; i <= cnt[g]; ++i) {
ret += mu[d[i]] * (n / d[i]);
}
return ret;
}
int main () {
cin >> n, mu[1] = 1;
for (int i = 2; i < N; ++i) {
if (!vis[i]) {
p[++p[0]] = i, mu[i] = -1;
}
for (int j = 1; j <= p[0] && i * p[j] < N; ++j) {
vis[i * p[j]] = 1;
if (i % p[j] == 0) {
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = -mu[i];
}
}
m = sqrt(n * 2);
for (int i = 1; i <= m; ++i) {
if (mu[i]) {
for (int j = i; j <= m; j += i) {
++cnt[j];
}
}
cnt[i] += cnt[i - 1];
}
for (int i = 1; i <= m; ++i) {
if (mu[i]) {
for (int j = i; j <= m; j += i) {
d[cnt[j - 1] + (++tmp[j])] = i;
}
}
}
for (int g = 1; g <= m; ++g) {
ans += calc(g, min(n / g, 0ll + g - 1)) - calc(g, max(0ll + g - n / g, 1ll) - 1);
}
cout << ans << endl;
return 0;
}