#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
bool isprime[N];
vector<int> prime;
int mobius[N];
int phi[N];
int phi_pref[N];
void init() {
fill(isprime, isprime + N, true);
isprime[0] = isprime[1] = false;
mobius[1] = 1;
phi[1] = 1;
for(int i = 2; i < N; ++i) {
if(isprime[i]) {
prime.push_back(i);
mobius[i] = -1;
phi[i] = i - 1;
}
for(auto& p : prime) {
if(p * i >= N) {
break;
}
isprime[p * i] = false;
mobius[p * i] = mobius[p] * mobius[i];
phi[p * i] = phi[p] * phi[i];
if(i % p == 0) {
mobius[p * i] = 0;
phi[p * i] = phi[i] * p;
break;
}
}
}
for(int i = 1; i < N; ++i) {
phi_pref[i] = phi_pref[i - 1] + phi[i];
}
}
int main(int argc, char* argv[]) {
ios::sync_with_stdio(false);
cin.tie(0);
init();
int n;
while(cin >> n && n) {
long long ans = 0;
for(int i = 1, j; i <= n; i = j) {
int p = n / i;
j = n / p + 1;
ans += 1LL * p * (p - 1) / 2 * (phi_pref[j - 1] - phi_pref[i - 1]);
}
cout << ans << "\n";
}
return 0;
}
I think
phi_prefis overflowingThank you! I somehow thought that I'm doing prefix sums on mobius and use int instead of long long since mobius only has -1, 0, 1 and won't overflow.