voidinit(){ // 预处理 std::vector<int> pri; std::vector<bool> notPrime(MAX_N + 1, false); mu[1] = phi[1] = 1; for (int i = 2; i <= MAX_N; i++) { if (!notPrime[i]) { pri.push_back(i); mu[i] = -1; phi[i] = i - 1; } for (int p : pri) { if (i * p > MAX_N) break; notPrime[i * p] = true; if (i % p == 0) { mu[i * p] = 0; phi[i * p] = phi[i] * p; break; } mu[i * p] = -mu[i]; phi[i * p] = phi[i] * (p - 1); } } for (int i = 2; i <= MAX_N; i++) { mu[i] += mu[i - 1]; phi[i] += phi[i - 1]; } }
std::unordered_map<int, int> mob_res; intmobius_sum(int n){ if (mob_res.find(n) != mob_res.end()) return mob_res[n]; if (n <= MAX_N) return mu[n]; i64 res = 1; i64 left = 2, right; while (left <= n) { right = n / (n / left); res -= (right - left + 1) * mobius_sum(n / left); left = right + 1; }
return mob_res[n] = res; }
std::unordered_map<int, i64> phi_res; i64 phi_sum(i64 n){ if (phi_res.find(n) != phi_res.end()) return phi_res[n]; if (n <= MAX_N) return phi[n]; i64 res = (i64)n * (n + 1) / 2; i64 left = 2, right; while (left <= n) { right = n / (n / left); res -= (right - left + 1) * phi_sum(n / left); left = right + 1; }
constint MAX_N = 5e4 + 5; int mu[MAX_N]; bool notPrime[MAX_N]; voidinit(){ mu[1] = 1; std::vector<int> pri; for (int i = 2; i < MAX_N; i++) { if (!notPrime[i]) { mu[i] = -1; pri.push_back(i); } for (int p : pri) { if (i * p >= MAX_N) break; notPrime[i * p] = true; if (i % p == 0) { mu[i * p] = 0; break; } mu[i * p] = -mu[i]; } }
for (int i = 1; i < MAX_N; i++) mu[i] += mu[i - 1]; }
intsolve(int m, int n){ int res = 0; for (int l = 1, r, b = std::min(m, n); l <= b; l = r + 1) { r = std::min(m / (m / l), n / (n / l)); res += (mu[r] - mu[l - 1]) * (m / l) * (n / l); }