All Euler problems
Project Euler

Retractions C

An affine map f_(n,a,b)(x) = ax + b (mod n) with a, b in {0, 1,..., n-1} is a retraction if f circ f = f, i.e., f(f(x)) equiv f(x) (mod n) for all x. Let R(n) denote the number of retractions for n...

Source sync Apr 19, 2026
Problem #0447
Level Level 26
Solved By 392
Languages C++, Python
Answer 530553372
Length 347 words
modular_arithmeticnumber_theorybrute_force

Problem Statement

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

For every integer $n > 1$, the family of functions $f_{n,a,b}$ is defined by $$f_{n,a,b}(x)\equiv a x + b \pmod{n}\,\,\, \text{for } a,b,x \text{ integer and } 0 < a < n, 0\leq b < n, 0 \leq x < n$$

We will call $f_{n, a, b}$ a retraction if $f_{n, a, b}\left(f_{n, a, b} (x)\right) \equiv f_{n, a, b} (x) \pmod{n}$ for every $0 \leq x < n$.

Let $R(n)$ be the number of retractions for $n$.

Let $F(n) = \displaystyle \sum_{n = 1}^{N} R(n^4 + 4)$. We have $F(10^7)\equiv 638042271 \mod 1\,000\,000\,007$.

Find $F(10^{14})$. Give your answer modulo $1\,000\,000\,007$.

Problem 447: Retractions C

Mathematical Foundation

Theorem 1 (Retraction Characterization). The map f(x)=ax+bf(x) = ax + b is a retraction modulo nn if and only if:

  1. a2a(modn)a^2 \equiv a \pmod{n} (idempotent multiplier), and
  2. ab0(modn)ab \equiv 0 \pmod{n} (translation compatibility).

Proof. Composing: f(f(x))=a(ax+b)+b=a2x+(ab+b)f(f(x)) = a(ax + b) + b = a^2 x + (ab + b). Setting f(f(x))f(x)=ax+b(modn)f(f(x)) \equiv f(x) = ax + b \pmod{n} for all xx: the coefficient of xx gives a2aa^2 \equiv a, and the constant term gives ab+bbab + b \equiv b, i.e., ab0(modn)ab \equiv 0 \pmod{n}. \square

Theorem 2 (Product Formula). For n=p1e1prern = p_1^{e_1} \cdots p_r^{e_r},

R(n)=i=1r(1+piei).R(n) = \prod_{i=1}^{r} (1 + p_i^{e_i}).

In particular, RR is a multiplicative arithmetic function.

Proof. The idempotent condition a(a1)0(modn)a(a-1) \equiv 0 \pmod{n} decomposes via CRT. Since gcd(a,a1)=1\gcd(a, a-1) = 1, for each prime power penp^e \| n, we must have either peap^e \mid a or pe(a1)p^e \mid (a-1). This gives 2ω(n)2^{\omega(n)} idempotent values of aa in {0,1,,n1}\{0, 1, \ldots, n-1\}.

For each idempotent aa, the condition ab0(modn)ab \equiv 0 \pmod{n} has exactly gcd(a,n)\gcd(a, n) solutions b{0,,n1}b \in \{0, \ldots, n-1\}. By CRT, the total count factors over prime powers. At pep^e:

  • a0(modpe)a \equiv 0 \pmod{p^e}: gcd(a,pe)=pe\gcd(a, p^e) = p^e, contributing pep^e valid values of bb.
  • a1(modpe)a \equiv 1 \pmod{p^e}: gcd(a,pe)=1\gcd(a, p^e) = 1, contributing 11 valid value of bb.

Local factor: pe+1p^e + 1. By CRT independence, R(n)=pen(1+pe)R(n) = \prod_{p^e \| n}(1 + p^e). \square

Lemma 1 (Verification for Small Values).

nnFactorizationR(n)R(n)Direct check
2212^11+2=31 + 2 = 3a{0,1}a \in \{0,1\}: gcd(0,2)+gcd(1,2)=2+1=3\gcd(0,2)+\gcd(1,2) = 2+1 = 3
3313^11+3=41 + 3 = 4a{0,1}a \in \{0,1\}: 3+1=43 + 1 = 4
4222^21+4=51 + 4 = 5a{0,1}a \in \{0,1\}: 4+1=54 + 1 = 5
6232 \cdot 3(1+2)(1+3)=12(1+2)(1+3) = 12a{0,1,3,4}a \in \{0,1,3,4\}: 6+1+3+2=126+1+3+2 = 12

Proof. Direct enumeration confirms each entry. For n=6n = 6: the idempotents mod 6 are a{0,1,3,4}a \in \{0, 1, 3, 4\} (by CRT: amod2{0,1}a \bmod 2 \in \{0,1\}, amod3{0,1}a \bmod 3 \in \{0,1\}). The gcd\gcd values are gcd(0,6)=6\gcd(0,6) = 6, gcd(1,6)=1\gcd(1,6) = 1, gcd(3,6)=3\gcd(3,6) = 3, gcd(4,6)=2\gcd(4,6) = 2. Sum: 6+1+3+2=12=(1+2)(1+3)6 + 1 + 3 + 2 = 12 = (1+2)(1+3). \square

Lemma 2 (Linear Sieve Correctness). Since RR is multiplicative with R(pe)=1+peR(p^e) = 1 + p^e, the linear sieve decomposition n=pemn = p^e \cdot m with gcd(m,p)=1\gcd(m, p) = 1 and p=spf(n)p = \operatorname{spf}(n) gives the exact recurrence R(n)=R(m)(1+pe)R(n) = R(m) \cdot (1 + p^e).

Proof. Multiplicativity of RR and the coprimality gcd(m,pe)=1\gcd(m, p^e) = 1 (since p=spf(n)p = \operatorname{spf}(n) and m=n/pem = n/p^e has all prime factors >p> p) give R(n)=R(pe)R(m)=(1+pe)R(m)R(n) = R(p^e) \cdot R(m) = (1 + p^e) \cdot R(m). \square

Editorial

The number of retractions R(n) for affine maps f(x) = ax + b mod n equals the number of pairs (a, b) with a^2 ≡ a (mod n) and ab ≡ 0 (mod n). Key result: R(n) = prod_{p^e || n} (1 + p^e), a multiplicative function. We compute sum_{n=2}^{N} R(n) mod (10^9 + 7) using a linear sieve. We linear sieve for smallest prime factor. We then compute R(n) using multiplicative structure. Finally, extract p^e from n.

Pseudocode

Linear sieve for smallest prime factor
Compute R(n) using multiplicative structure
Extract p^e from n

Complexity Analysis

  • Time: O(N)O(N). The smallest prime factor sieve runs in O(N)O(N) with a linear sieve. Computing R(n)R(n) for each nn takes O(logn)O(\log n) for extracting pep^e, but amortized over all nn this is O(N)O(N) (each integer is divided by its smallest prime factor a bounded number of times). The summation is O(N)O(N).
  • Space: O(N)O(N) for the arrays spf[1..N]\operatorname{spf}[1..N] and R[1..N]R[1..N].

Answer

530553372\boxed{530553372}

Code

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

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

/*
 * Problem 447: Retractions B
 *
 * R(n) = number of affine retractions f(x) = ax + b (mod n), i.e.,
 *        pairs (a,b) with a^2 ≡ a (mod n) and ab ≡ 0 (mod n).
 *
 * Key formula: R(n) = prod_{p^e || n} (1 + p^e).
 * R is multiplicative, computed via linear sieve.
 *
 * Answer: sum_{n=2}^{10^7} R(n) mod (10^9 + 7).
 */

const long long MOD = 1e9 + 7;
const int N = 10000000;

int spf[N + 1];         // smallest prime factor
long long R_val[N + 1]; // R(n) mod MOD

void compute_spf() {
    for (int i = 0; i <= N; i++) spf[i] = i;
    for (int i = 2; (long long)i * i <= N; i++) {
        if (spf[i] == i) { // i is prime
            for (int j = i * i; j <= N; j += i) {
                if (spf[j] == j) spf[j] = i;
            }
        }
    }
}

int main() {
    compute_spf();

    R_val[1] = 1;
    long long total = 0;

    for (int n = 2; n <= N; n++) {
        int p = spf[n];
        // Extract p^e from n
        int m = n;
        long long pe = 1;
        while (m % p == 0) {
            m /= p;
            pe *= p;
        }
        // R(n) = R(m) * (1 + p^e) mod MOD
        R_val[n] = R_val[m] % MOD * ((1 + pe) % MOD) % MOD;
        total = (total + R_val[n]) % MOD;
    }

    cout << total << endl;

    // Verification for small cases
    // R(2) = 3, R(3) = 4, R(4) = 5, R(6) = 12
    assert(R_val[2] == 3);
    assert(R_val[3] == 4);
    assert(R_val[4] == 5);
    assert(R_val[6] == 12);
    assert(R_val[12] == 20);
    assert(R_val[30] == 72);

    return 0;
}