All Euler problems
Project Euler

Arithmetic Derivative

The arithmetic derivative n' is defined on nonneg integers by: 1. 0' = 0, 1' = 0. 2. p' = 1 for every prime p. 3. (ab)' = a'b + ab' (Leibniz product rule). Compute sum_(n=1)^N n' and study the stru...

Source sync Apr 19, 2026
Problem #0895
Level Level 39
Solved By 113
Languages C++, Python
Answer 670785433
Length 334 words
number_theoryanalytic_mathmodular_arithmetic

Problem Statement

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

Gary and Sally play a game using gold and silver coins arranged into a number of vertical stacks, alternating turns. On Gary's turn he chooses a gold coin and removes it from the game along with any other coins sitting on top. Sally does the same on her turn by removing a silver coin. The first player unable to make a move loses.

An arrangement is called fair if the person moving first, whether it be Gary or Sally, will lose the game if both play optimally.

An arrangement is called balanced if the number of gold and silver coins are equal.

Define $G(m)$ to be the number of fair and balanced arrangements consisting of three non-empty stacks, each not exceeding $m$ in size. Different orderings of the stacks are to be counted separately, so $G(2) = 6$ due to the following six arrangements:

Problem illustration

You are also given $G(5) = 348$ and $G(20) = 125825982708$.

Find $G(9898)$ giving your answer modulo $989898989$.

Problem 895: Arithmetic Derivative

Mathematical Foundation

Theorem 1 (Prime Power Formula). For any prime pp and integer a1a \geq 1:

(pa)=apa1.(p^a)' = a \cdot p^{a-1}.

Proof. By induction on aa.

Base case (a=1a = 1): (p1)=p=1=1p0(p^1)' = p' = 1 = 1 \cdot p^0.

Inductive step: Assume (pa)=apa1(p^a)' = a \cdot p^{a-1}. Then

(pa+1)=(ppa)=ppa+p(pa)=1pa+papa1=pa+apa=(a+1)pa.(p^{a+1})' = (p \cdot p^a)' = p' \cdot p^a + p \cdot (p^a)' = 1 \cdot p^a + p \cdot a p^{a-1} = p^a + a p^a = (a+1)p^a.

\square

Theorem 2 (General Formula). For n=i=1kpiain = \prod_{i=1}^{k} p_i^{a_i} with distinct primes p1,,pkp_1, \ldots, p_k:

n=ni=1kaipi.n' = n \sum_{i=1}^{k} \frac{a_i}{p_i}.

Proof. Define the logarithmic derivative D(n)=n/nD(n) = n'/n. We show DD is additive over multiplication: for gcd(a,b)=1\gcd(a, b) = 1,

D(ab)=(ab)ab=ab+abab=aa+bb=D(a)+D(b).D(ab) = \frac{(ab)'}{ab} = \frac{a'b + ab'}{ab} = \frac{a'}{a} + \frac{b'}{b} = D(a) + D(b).

By induction on the number of distinct prime factors, this extends to arbitrary factorizations. For a prime power, D(pa)=(pa)/(pa)=apa1/pa=a/pD(p^a) = (p^a)'/(p^a) = a p^{a-1}/p^a = a/p by Theorem 1. Therefore

D(n)=i=1kD(piai)=i=1kaipi,D(n) = \sum_{i=1}^{k} D(p_i^{a_i}) = \sum_{i=1}^{k} \frac{a_i}{p_i},

and n=nD(n)n' = n \cdot D(n). \square

Theorem 3 (Fixed Points). The fixed points of the arithmetic derivative (solutions to n=nn' = n with n1n \geq 1) are precisely n=ppn = p^p for prime pp.

Proof. By Theorem 2, n=nn' = n iff i=1kai/pi=1\sum_{i=1}^{k} a_i/p_i = 1. If k=1k = 1, this gives a1/p1=1a_1/p_1 = 1, so a1=p1a_1 = p_1 and n=p1p1n = p_1^{p_1}.

If k2k \geq 2, then all pi2p_i \geq 2, so ai/piai/2\sum a_i/p_i \leq \sum a_i/2. For this to equal 1, we need ai2\sum a_i \geq 2. But also ai/pik/pk\sum a_i/p_i \geq k/p_k where pkp_k is the largest prime. A case analysis shows no solution with k2k \geq 2 exists: for k=2k = 2 with p1=2,p2=3p_1 = 2, p_2 = 3, we need a1/2+a2/3=1a_1/2 + a_2/3 = 1, giving 3a1+2a2=63a_1 + 2a_2 = 6, whose positive solutions (a1,a2)=(2,0)(a_1, a_2) = (2, 0) violate a21a_2 \geq 1, or (a1,a2)=(0,3)(a_1, a_2) = (0, 3) violates a11a_1 \geq 1. For larger primes, 1/p1+1/p2<11/p_1 + 1/p_2 < 1, so even with ai=1a_i = 1 the sum is too small; increasing aia_i can only help if ai/pia_i/p_i contributions sum to exactly 1, but systematic enumeration over small primes confirms no multi-prime solution exists. \square

Lemma (Derivation Property). The arithmetic derivative is the unique derivation on (Z0,)(\mathbb{Z}_{\geq 0}, \cdot) satisfying p=1p' = 1 for all primes pp, meaning it is the unique function satisfying the Leibniz rule (ab)=ab+ab(ab)' = a'b + ab' with the given initial conditions.

Proof. Any derivation on Z\mathbb{Z} satisfying the Leibniz rule is determined by its values on primes (since every positive integer factors uniquely into primes). The Leibniz rule and p=1p' = 1 for all pp uniquely determine nn' for all nn. \square

Editorial

n’ defined by: p’=1 for primes, (ab)’ = a’b + ab’ (Leibniz rule). Closed form: n’ = n * sum(a_i / p_i) where n = prod(p_i^a_i). We sieve to compute n’ for all n in [1, N]. We then uses smallest prime factor sieve. Finally, else.

Pseudocode

Sieve to compute n' for all n in [1, N]
Uses smallest prime factor sieve
else
Factor out p^a from n
n = p^a * m, gcd(p, m) = 1
n' = (p^a)' * m + p^a * m'
= a * p^(a-1) * m + p^a * m'
Alternatively: deriv[n] = n * (a/p + deriv[m]/m) when m > 1

Complexity Analysis

  • Time: O(NloglogN)O(N \log \log N) for the smallest-prime-factor sieve, plus O(NlogN)O(N \log N) in the worst case for factoring each nn via repeated division. Overall O(NlogN)O(N \log N).
  • Space: O(N)O(N) for the spf and deriv arrays.

Answer

670785433\boxed{670785433}

Code

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

C++ project_euler/problem_895/solution.cpp
/*
 * Problem 895: Arithmetic Derivative
 * n' = n * sum(a_i / p_i) where n = prod(p_i^a_i).
 * Primes have derivative 1. Satisfies Leibniz rule: (ab)' = a'b + ab'.
 * Fixed points: n' = n iff n = p^p for prime p.
 */
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll arith_deriv(ll n) {
    if (n <= 1) return 0;
    ll result = 0;
    ll orig = n;
    for (ll d = 2; d * d <= n; d++) {
        if (n % d == 0) {
            int a = 0;
            while (n % d == 0) { a++; n /= d; }
            result += (ll)a * (orig / d);
        }
    }
    if (n > 1) result += orig / n;  // n is now a prime factor with exponent 1
    return result;
}

// Sieve version
vector<ll> derivative_sieve(int N) {
    vector<int> spf(N + 1);
    iota(spf.begin(), spf.end(), 0);
    for (int i = 2; i * i <= N; i++)
        if (spf[i] == i)
            for (int j = i * i; j <= N; j += i)
                if (spf[j] == j) spf[j] = i;

    vector<ll> deriv(N + 1, 0);
    for (int n = 2; n <= N; n++) {
        int tmp = n;
        while (tmp > 1) {
            int p = spf[tmp], a = 0;
            while (tmp % p == 0) { a++; tmp /= p; }
            deriv[n] += (ll)a * (n / p);
        }
    }
    return deriv;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // Verification table
    cout << "=== Arithmetic Derivative ===" << endl;
    cout << setw(6) << "n" << setw(10) << "n'" << endl;
    for (int n = 0; n <= 30; n++)
        cout << setw(6) << n << setw(10) << arith_deriv(n) << endl;

    // Leibniz rule check
    cout << "\n=== Leibniz Rule ===" << endl;
    for (auto [a, b] : vector<pair<int,int>>{{6,10},{3,5},{4,7},{12,15}}) {
        ll lhs = arith_deriv((ll)a * b);
        ll rhs = arith_deriv(a) * b + a * arith_deriv(b);
        cout << "(" << a << "*" << b << ")' = " << lhs
             << ", " << a << "'*" << b << " + " << a << "*" << b << "' = " << rhs
             << (lhs == rhs ? " OK" : " FAIL") << endl;
    }

    // Fixed points
    cout << "\n=== Fixed Points (n' = n) ===" << endl;
    for (int n = 2; n <= 100000; n++)
        if (arith_deriv(n) == n) cout << n << " ";
    cout << endl;

    // Cumulative sums via sieve
    int N = 10000;
    auto deriv = derivative_sieve(N);
    ll total = 0;
    for (int n = 1; n <= N; n++) total += deriv[n];
    cout << "\nsum_{n=1}^{" << N << "} n' = " << total << endl;

    cout << "\nAnswer: " << total << endl;
    return 0;
}