求 S(n) = ∑_{1≤if(n) = ∑_{i=1}^{n-1} gcd(i,n),則 S(n) = S(n-1) + f(n)。
關鍵:f(n) = ∑_{d|n} d × φ(n/d),其中 d 遍歷 n 的因子。
const int N = 4000000;
int phi[N+5]; ll f[N+5], s[N+5];
void phi_table(int n) {
for (int i = 2; i <= n; i++) phi[i] = 0;
phi[1] = 1;
for (int i = 2; i <= n; i++) if (!phi[i])
for (int j = i; j <= n; j += i) {
if (!phi[j]) phi[j] = j;
phi[j] = phi[j] / i * (i-1);
}
}
int main() {
phi_table(N);
for (int i = 1; i <= N; i++)
for (int j = i*2; j <= N; j += i)
f[j] += i * phi[j/i];
s[2] = f[2];
for (int i = 3; i <= N; i++) s[i] = s[i-1] + f[i];
int n; while (scanf("%d",&n) && n) printf("%lld\n", s[n]);
}
關鍵優化:內層循環 j = i*2 從 2i 開始,避免 i=j 產生 gcd(n,n)=n 的情況(題目要求 i≠j)。