Test Instructions Order G (n) = SUM{GCD (i, J) | 0 < i < n, i < J <= N} give you an n output g (n)
make F (n) = SUM{GCD (i, N) | 0 < i < n}
so there's a recursive type g (n) = g (n-1) + F (n), g (0) = 0
In other words, f (n) can be used to deduce the G (n) and the F (n) is easier to find.
for I set x < I, gcd (x,i) = 1 i.e. x, n coprime
the gcd (2*x, 2*i) = 2, gcd (3*x, 3*i) = 3, ..., gcd (k*x, k*i) = k
So the number of x is the Euler function of I, then we find the Euler functions of I and all f (k*i) with K so that the sieve will be able to find a certain range of F function value and then add up is the function value of g
#include <cstdio>const int N = 4000005;typedef long long ll;int phi[n];ll g[n];void init ()//o (N*LOGN) sieve Euler function {for (int i = 2; i < N; ++i) phi[i] = i; for (int i = 2; i < N; i + +) { if (phi[i] = = i)//i is a prime number {for (int j = i; J < N; J + = i) phi[j] = ph I[J]/I * (i-1); Need to remove a factor i from J because Phi (p^k) = (p-1) * p^ (k-1) } for (int j = 1; J * I < N; j + +) g[j * I] + = J * Phi[i ]; Phi[i] is less than I and the number of I coprime J * I < N when J * x must also be less than N } for (int i = 1; i < N; i + +) G[i] + + g[i-1];} int main () { init (); int n; while (scanf ("%d", &n), N) printf ("%lld\n", G[n]); return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
UVa 11426 Gcd-extreme (II) (Euler function application · O (N*LOGN))