All Euler problems
Project Euler

Average Least Common Multiple

Define the average LCM function: f(n) = (1)/(n) sum_(k=1)^n lcm(k, n). Compute S(N) = sum_(n=1)^N f(n) (mod 10^9 + 7) for N = 10^8.

Source sync Apr 19, 2026
Problem #0448
Level Level 25
Solved By 422
Languages C++, Python
Answer 106467648
Length 214 words
modular_arithmeticnumber_theorybrute_force

Problem Statement

This archive keeps the full statement, math, and original media on the page.

The function \(\operatorname {\mathbf {lcm}}(a,b)\) denotes the least common multiple of \(a\) and \(b\).

Let \(A(n)\) be the average of the values of \(\operatorname {lcm}(n,i)\) for \(1 \le i \le n\).

E.g: \(A(2)=(2+2)/2=2\) and \(A(10)=(10+10+30+20+10+30+70+40+90+10)/10=32\).

Let \(S(n)=\displaystyle \sum A(k)\) for \(1 \le k \le n\). You are given that \(S(100)=122726\).

Find \(S(99999999019) \bmod 999999017\).

Problem 448: Average Least Common Multiple

Mathematical Foundation

Theorem 1 (Closed Form for f(n)f(n)). For all n1n \geq 1,

f(n)=1+dndφ(d)2.f(n) = \frac{1 + \displaystyle\sum_{d \mid n} d\,\varphi(d)}{2}.

Proof. Using lcm(k,n)=kn/gcd(k,n)\operatorname{lcm}(k,n) = kn/\gcd(k,n):

f(n)=1nk=1nkngcd(k,n)=k=1nkgcd(k,n).f(n) = \frac{1}{n}\sum_{k=1}^{n} \frac{kn}{\gcd(k,n)} = \sum_{k=1}^{n} \frac{k}{\gcd(k,n)}.

Group by g=gcd(k,n)g = \gcd(k,n): write k=gjk = gj where 1jn/g1 \leq j \leq n/g and gcd(j,n/g)=1\gcd(j, n/g) = 1. Setting d=n/gd = n/g:

f(n)=dnj=1gcd(j,d)=1dj=:dnΦ(d).f(n) = \sum_{d \mid n} \sum_{\substack{j=1 \\ \gcd(j,d)=1}}^{d} j =: \sum_{d \mid n} \Phi(d).

For d2d \geq 2, the coprime residues {j:1jd,gcd(j,d)=1}\{j : 1 \leq j \leq d,\, \gcd(j,d) = 1\} pair as jdjj \leftrightarrow d - j (both coprime to dd, and jdjj \neq d - j since d2d \geq 2 forces jd/2j \neq d/2 when gcd(d/2,d)1\gcd(d/2, d) \neq 1 for even dd, or dd is odd). Each pair sums to dd, and there are φ(d)/2\varphi(d)/2 pairs, so Φ(d)=dφ(d)/2\Phi(d) = d\,\varphi(d)/2.

For d=1d = 1: Φ(1)=1\Phi(1) = 1.

Therefore:

f(n)=1+dnd2dφ(d)2=1+dndφ(d)2f(n) = 1 + \sum_{\substack{d \mid n \\ d \geq 2}} \frac{d\,\varphi(d)}{2} = \frac{1 + \sum_{d \mid n} d\,\varphi(d)}{2}

where the last equality uses 1φ(1)=11 \cdot \varphi(1) = 1, so 1+d2dφ(d)/2=12+12+d2dφ(d)/2=1+dndφ(d)21 + \sum_{d \geq 2} d\varphi(d)/2 = \frac{1}{2} + \frac{1}{2} + \sum_{d \geq 2} d\varphi(d)/2 = \frac{1 + \sum_{d \mid n} d\varphi(d)}{2}. \square

Theorem 2 (Summation Formula). Define h(d)=dφ(d)h(d) = d\,\varphi(d). Then

S(N)=N+d=1Nh(d)N/d2.S(N) = \frac{N + \displaystyle\sum_{d=1}^{N} h(d)\,\lfloor N/d \rfloor}{2}.

Proof. Summing f(n)f(n) over n=1,,Nn = 1, \ldots, N:

S(N)=n=1N1+dnh(d)2=N+n=1Ndnh(d)2.S(N) = \sum_{n=1}^{N} \frac{1 + \sum_{d \mid n} h(d)}{2} = \frac{N + \sum_{n=1}^{N} \sum_{d \mid n} h(d)}{2}.

Swapping the order of summation: n=1Ndnh(d)=d=1Nh(d)N/d\sum_{n=1}^{N} \sum_{d \mid n} h(d) = \sum_{d=1}^{N} h(d) \cdot \lfloor N/d \rfloor, since h(d)h(d) contributes to each multiple of dd up to NN. \square

Lemma 1 (Multiplicativity of hh). The function h(n)=nφ(n)h(n) = n\,\varphi(n) is multiplicative, with h(pa)=p2ap2a1h(p^a) = p^{2a} - p^{2a-1} for primes pp and a1a \geq 1.

Proof. Both Id(n)=n\operatorname{Id}(n) = n and φ(n)\varphi(n) are multiplicative, so their product h=Idφh = \operatorname{Id} \cdot \varphi is multiplicative. For pap^a: h(pa)=papa1(p1)=p2a1(p1)=p2ap2a1h(p^a) = p^a \cdot p^{a-1}(p-1) = p^{2a-1}(p-1) = p^{2a} - p^{2a-1}. \square

Lemma 2 (Coprime Residue Pairing). For d2d \geq 2, if gcd(j,d)=1\gcd(j, d) = 1 and 1jd1 \leq j \leq d, then gcd(dj,d)=1\gcd(d-j, d) = 1 and j+(dj)=dj + (d-j) = d. Furthermore, jdjj \neq d - j (i.e., jd/2j \neq d/2) whenever d3d \geq 3, or d=2d = 2 with j=1j = 1.

Proof. gcd(dj,d)=gcd(j,d)=1\gcd(d-j, d) = \gcd(j, d) = 1. For j=d/2j = d/2 to be coprime to dd, we need gcd(d/2,d)=d/2=1\gcd(d/2, d) = d/2 = 1, so d=2d = 2. When d=2d = 2, the only coprime residue is j=1=d1j = 1 = d - 1, confirming the pairing is trivial (a single element). For d3d \geq 3, all pairs are distinct. \square

Editorial

*Alternative (Hyperbola Method):**. We sieve Euler’s totient function. We then compute h(d) = d * phi(d) mod mod for all d. Finally, compute S(N).

Pseudocode

Sieve Euler's totient function
Compute h(d) = d * phi(d) mod mod for all d
Divisor-sum convolution: g(n) = sum_{d | n} h(d)
Compute S(N)
Use S(N) = (N + sum_{d=1}^{N} h(d) * floor(N/d)) / 2
Group by distinct values of floor(N/d): O(sqrt(N)) groups

Complexity Analysis

  • Time (Direct method): O(NlogN)O(N \log N) dominated by the harmonic-series divisor convolution (d=1NN/d=O(NlnN)\sum_{d=1}^{N} N/d = O(N \ln N)).
  • Time (Hyperbola method): O(N)O(N) for the totient sieve and prefix sums, plus O(N)O(\sqrt{N}) for the grouped summation. Total: O(N)O(N).
  • Space: O(N)O(N) for the φ\varphi and HH arrays.

Answer

106467648\boxed{106467648}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_448/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 448: Average Least Common Multiple
 *
 * f(n) = (1/n) * sum_{k=1}^{n} lcm(k, n)
 *       = (1 + sum_{d|n} d*phi(d)) / 2
 *
 * S(N) = sum_{n=1}^{N} f(n) mod (10^9 + 7).
 *
 * Algorithm:
 *   1. Sieve phi(n) for n = 1..N.
 *   2. Compute h(n) = n * phi(n) mod p.
 *   3. Compute g(n) = sum_{d|n} h(d) mod p via additive sieve.
 *   4. f(n) = (1 + g(n)) / 2 mod p.
 *   5. Sum all f(n).
 */

const long long MOD = 1e9 + 7;
const long long INV2 = (MOD + 1) / 2;  // modular inverse of 2
const int N = 100000000;  // 10^8

int phi_arr[N + 1];
long long g[N + 1];  // sum_{d|n} d*phi(d) mod MOD

int main() {
    // Step 1: Euler totient sieve
    for (int i = 0; i <= N; i++) phi_arr[i] = i;
    for (int i = 2; i <= N; i++) {
        if (phi_arr[i] == i) {  // i is prime
            for (int j = i; j <= N; j += i) {
                phi_arr[j] = phi_arr[j] / i * (i - 1);
            }
        }
    }

    // Steps 2-3: Compute g(n) = sum_{d|n} d*phi(d)
    memset(g, 0, sizeof(g));
    for (int d = 1; d <= N; d++) {
        long long hd = (long long)d % MOD * (phi_arr[d] % MOD) % MOD;
        for (int multiple = d; multiple <= N; multiple += d) {
            g[multiple] = (g[multiple] + hd) % MOD;
        }
    }

    // Steps 4-5: f(n) = (1 + g(n)) * inv2, sum all
    long long total = 0;
    for (int n = 1; n <= N; n++) {
        long long fn = (1 + g[n]) % MOD * INV2 % MOD;
        total = (total + fn) % MOD;
    }

    cout << total << endl;

    // Verification
    assert(total == 106467648LL);

    return 0;
}