All Euler problems
Project Euler

Integer-valued Polynomials

The polynomial n^4 + 4n^3 + 2n^2 + 5n is a multiple of 6 for every integer n, and 6 is the largest such integer. Define M(a, b, c) as the maximum m such that n^4 + an^3 + bn^2 + cn is a multiple of...

Source sync Apr 19, 2026
Problem #0402
Level Level 23
Solved By 504
Languages C++, Python
Answer 356019862
Length 454 words
modular_arithmeticlinear_algebranumber_theory

Problem Statement

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

It can be shown that the polynomial \(n^4 + 4n^3 + 2n^2 + 5n\) is a multiple of \(6\) for every integer \(n\). It can also be shown that \(6\) is the largest integer satisfying this property.

Define \(M(a, b, c)\) as the maximum \(m\) such that \(n^4 + an^3 + bn^2 + cn\) is a multiple of \(m\) for all integers \(n\). For example, \(M(4, 2, 5) = 6\).

Also, define \(S(N)\) as the sum of \(M(a, b, c)\) for all \(0 < a, b, c \leq N\).

We can verify that \(S(10) = 1972\) and \(S(10000) = 2024258331114\).

Let \(F_k\) be the Fibonacci sequence: \begin {equation} \begin {cases} F_0 = 0 \\ F_1 = 1 \\ F_k = F_{k - 1} + F_{k - 2}, \quad \text {for } k \geq 2 \end {cases} \end {equation}

Find the last \(9\) digits of \(\sum S(F_k)\) for \(2 \leq k \leq 1234567890123\).

Problem 402: Integer-valued Polynomials

Mathematical Foundation

Theorem 1 (Binomial basis characterization of M(a,b,c)M(a,b,c)). For integers a,b,ca, b, c,

M(a,b,c)=gcd ⁣(24,  36+6a,  14+6a+2b,  1+a+b+c).M(a,b,c) = \gcd\!\big(24,\; 36+6a,\; 14+6a+2b,\; 1+a+b+c\big).

Proof. A polynomial p(n)=k=0dck(nk)p(n) = \sum_{k=0}^{d} c_k \binom{n}{k} satisfies mp(n)m \mid p(n) for all nZn \in \mathbb{Z} if and only if mckm \mid c_k for every kk. This is because the binomial coefficients (n0),(n1),\binom{n}{0}, \binom{n}{1}, \ldots form a Z\mathbb{Z}-basis for the ring of integer-valued polynomials, and (nk)Z\binom{n}{k} \in \mathbb{Z} for all nZn \in \mathbb{Z}.

Lemma 1 (Newton forward-difference expansion). The monomials expand as:

n=(n1),n2=2(n2)+(n1),n3=6(n3)+6(n2)+(n1),n = \binom{n}{1}, \quad n^2 = 2\binom{n}{2} + \binom{n}{1}, \quad n^3 = 6\binom{n}{3} + 6\binom{n}{2} + \binom{n}{1}, n4=24(n4)+36(n3)+14(n2)+(n1).n^4 = 24\binom{n}{4} + 36\binom{n}{3} + 14\binom{n}{2} + \binom{n}{1}.

Proof. By the Stirling number identity nk=j=0kS(k,j)j!(nj)n^k = \sum_{j=0}^{k} S(k,j) \cdot j! \cdot \binom{n}{j}, where S(k,j)S(k,j) are Stirling numbers of the second kind. Direct computation gives the stated coefficients. \square

Applying the lemma, p(n)=n4+an3+bn2+cnp(n) = n^4 + an^3 + bn^2 + cn has binomial coefficients:

d4=24,d3=36+6a,d2=14+6a+2b,d1=1+a+b+c.d_4 = 24, \quad d_3 = 36 + 6a, \quad d_2 = 14 + 6a + 2b, \quad d_1 = 1 + a + b + c.

The maximum universal divisor is M(a,b,c)=gcd(d1,d2,d3,d4)M(a,b,c) = \gcd(d_1, d_2, d_3, d_4). \square

Theorem 2 (Euler totient decomposition). Since M(a,b,c)24M(a,b,c) \mid 24, we have

S(N)=d24φ(d)#{(a,b,c)[1,N]3:dM(a,b,c)}S(N) = \sum_{d \mid 24} \varphi(d) \cdot \#\{(a,b,c) \in [1,N]^3 : d \mid M(a,b,c)\}

where φ\varphi is Euler’s totient function.

Proof. By the identity n=dnφ(d)n = \sum_{d \mid n} \varphi(d), we have M(a,b,c)=dM(a,b,c)φ(d)M(a,b,c) = \sum_{d \mid M(a,b,c)} \varphi(d). Summing over all triples and interchanging:

S(N)=(a,b,c)dM(a,b,c)φ(d)=d24φ(d)(a,b,c)dM(a,b,c)1.S(N) = \sum_{(a,b,c)} \sum_{d \mid M(a,b,c)} \varphi(d) = \sum_{d \mid 24} \varphi(d) \sum_{\substack{(a,b,c) \\ d \mid M(a,b,c)}} 1. \quad \square

Lemma 2 (Piecewise-cubic structure). For each residue s=Nmod24s = N \bmod 24, the function S(N)S(N) is a cubic polynomial in NN:

288S(N)=AsN3+BsN2+CsN+Ds,Ns(mod24),288 \cdot S(N) = A_s N^3 + B_s N^2 + C_s N + D_s, \quad N \equiv s \pmod{24},

where As=583A_s = 583 for all ss.

Proof. The condition dM(a,b,c)d \mid M(a,b,c) reduces to three congruences modulo dd on (a,b,c)(a, b, c). For each valid residue class, the count of triples in [1,N]3[1,N]^3 is a product of three terms of the form (Nr)/d\lfloor (N - r)/d \rfloor, each piecewise-linear in NN with period dd. The product is piecewise-cubic with period lcm\operatorname{lcm} of all d24d \mid 24, which is 2424. The factor 288=lcm288 = \operatorname{lcm} of the coefficient denominators ensures integrality. \square

Theorem 3 (Matrix exponentiation for Fibonacci power sums). For each residue class rmod24r \bmod 24, the subsequence (F24i+r)(F_{24i+r}) satisfies a two-term linear recurrence. The sums F24i+rj\sum F_{24i+r}^j for j=0,1,2,3j = 0, 1, 2, 3 are computed via a 1414-dimensional linear recurrence solved by matrix exponentiation.

Proof. The Pisano period π(24)=24\pi(24) = 24, so Fkmod24F_k \bmod 24 depends only on kmod24k \bmod 24. The matrix A24A^{24} where A=(1110)A = \bigl(\begin{smallmatrix}1&1\\1&0\end{smallmatrix}\bigr) advances the Fibonacci sequence by 24 steps: (Fk+24,Fk+25)=M24(Fk,Fk+1)(F_{k+24}, F_{k+25}) = M_{24}(F_k, F_{k+1}).

Define the state vector of dimension 14:

x=(u3,u2v,uv2,v3,u2,uv,v2,u,v,1,Σu3,Σu2,Σu,Σ1)\mathbf{x} = (u^3, u^2v, uv^2, v^3, u^2, uv, v^2, u, v, 1, \Sigma u^3, \Sigma u^2, \Sigma u, \Sigma 1)

where u=F24i+ru = F_{24i+r}, v=F24i+r+1v = F_{24i+r+1}. The transition (u,v)(F23u+F24v,  F24u+F25v)(u,v) \to (F_{23}u + F_{24}v,\; F_{24}u + F_{25}v) is linear, and all monomials up to degree 3 in (u,v)(u,v) transform linearly. The accumulators track running sums. This yields a 14×1414 \times 14 transition matrix TT, and TNT^{N} is computed via repeated squaring in O(143logN)O(14^3 \log N) operations. \square

Editorial

The polynomial n^4 + 4n^3 + 2n^2 + 5n is a multiple of 6 for every integer n. Define M(a,b,c) as the maximum m such that n^4 + an^3 + bn^2 + cn is a multiple of m for all integers n. So M(4,2,5) = 6. Define S(N) = sum of M(a,b,c) for 0 < a,b,c <= N. Given: S(10) = 1972, S(10000) = 2024258331114. With Fibonacci F_0=0, F_1=1, F_k = F_{k-1}+F_{k-2}: Find last 9 digits of sum_{k=2}^{1234567890123} S(F_k). We precompute the 24 cubic polynomials (A_s, B_s, C_s, D_s). We then by fitting S(N) at 4 sample points per residue class s mod 24. Finally, iterate over each residue class r = 0..23 of k mod 24.

Pseudocode

Precompute the 24 cubic polynomials (A_s, B_s, C_s, D_s)
by fitting S(N) at 4 sample points per residue class s mod 24
For each residue class r = 0..23 of k mod 24:
Determine which polynomial to use: s = F_r mod 24 (Pisano period)
Build 14x14 transition matrix T for subsequence F_{24i+r}
Determine number of terms in subsequence with index k in [2, K], k ≡ r (mod 24)
Matrix exponentiation: T^{n_terms - 1} applied to initial state
Extract accumulated sums: Σu^3, Σu^2, Σu, Σ1
Divide by 288 and reduce modulo MOD

Complexity Analysis

  • Time: O(14324logK)O(106)O(14^3 \cdot 24 \cdot \log K) \approx O(10^6) for K=1.23×1012K = 1.23 \times 10^{12}. The dominant cost is 24 matrix exponentiations of 14×1414 \times 14 matrices with exponents K/24\sim K/24.
  • Space: O(142)=O(1)O(14^2) = O(1). Only a constant number of matrices and vectors.

Answer

356019862\boxed{356019862}

Code

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

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

/*
 * Project Euler Problem 402: Integer-valued Polynomials
 *
 * M(a,b,c) = gcd(24, 36+6a, 14+6a+2b, 1+a+b+c)
 * S(N) = sum_{0<a,b,c<=N} M(a,b,c)
 * Find last 9 digits of sum_{k=2}^{1234567890123} S(F_k)
 *
 * Answer: 356019862
 */

typedef long long ll;
typedef __int128 lll;
typedef vector<vector<ll>> Matrix;

const ll MOD_FINAL = 1000000000LL;       // 10^9
const ll WORK_MOD  = 288LL * MOD_FINAL;  // 288 * 10^9

// =====================================================================
// Safe modular reduction for __int128
// =====================================================================

inline ll mmod(lll x) {
    ll r = (ll)(x % WORK_MOD);
    return r < 0 ? r + WORK_MOD : r;
}

// =====================================================================
// Matrix operations mod WORK_MOD
// =====================================================================

Matrix mat_mul(const Matrix& A, const Matrix& B) {
    int n = A.size(), m = B[0].size(), k = B.size();
    Matrix C(n, vector<ll>(m, 0));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            lll s = 0;
            for (int l = 0; l < k; l++)
                s += (lll)A[i][l] * B[l][j];
            C[i][j] = mmod(s);
        }
    return C;
}

Matrix mat_pow(Matrix A, ll p) {
    int n = A.size();
    Matrix result(n, vector<ll>(n, 0));
    for (int i = 0; i < n; i++) result[i][i] = 1;
    while (p > 0) {
        if (p & 1) result = mat_mul(result, A);
        A = mat_mul(A, A);
        p >>= 1;
    }
    return result;
}

vector<ll> mat_vec(const Matrix& A, const vector<ll>& v) {
    int n = A.size();
    vector<ll> result(n, 0);
    for (int i = 0; i < n; i++) {
        lll s = 0;
        for (int j = 0; j < (int)v.size(); j++)
            s += (lll)A[i][j] * v[j];
        result[i] = mmod(s);
    }
    return result;
}

// =====================================================================
// S(N) analytical computation (for verification)
// =====================================================================

int euler_totient(int n) {
    int result = n, temp = n;
    for (int p = 2; p * p <= temp; p++) {
        if (temp % p == 0) {
            while (temp % p == 0) temp /= p;
            result -= result / p;
        }
    }
    if (temp > 1) result -= result / temp;
    return result;
}

ll S_analytical(ll N) {
    int divs[] = {1, 2, 3, 4, 6, 8, 12, 24};
    ll total = 0;
    for (int d : divs) {
        int phi_d = euler_totient(d);
        ll cnt = 0;
        for (int ar = 0; ar < d; ar++) {
            if ((36 + 6 * ar) % d != 0) continue;
            int first_a = (ar >= 1) ? ar : d;
            if (first_a > N) continue;
            ll cnt_a = (N - first_a) / d + 1;
            for (int br = 0; br < d; br++) {
                if ((14 + 6 * ar + 2 * br) % d != 0) continue;
                int first_b = (br >= 1) ? br : d;
                if (first_b > N) continue;
                ll cnt_b = (N - first_b) / d + 1;
                int cr = ((-(1 + ar + br)) % d + d) % d;
                int first_c = (cr >= 1) ? cr : d;
                if (first_c > N) continue;
                ll cnt_c = (N - first_c) / d + 1;
                cnt += cnt_a * cnt_b * cnt_c;
            }
        }
        total += (ll)phi_d * cnt;
    }
    return total;
}

// =====================================================================
// Piecewise-cubic polynomial coefficients for 288 * S(N)
// 288*S(N) = A*N^3 + B*N^2 + C*N + D when N ≡ s (mod 24)
// =====================================================================

struct Poly { ll D, C, B, A; };

Poly POLYS[24] = {
    {0, 0, 0, 583},           // s=0
    {257, -75, -189, 583},    // s=1
    {520, 84, 102, 583},      // s=2
    {1215, -27, -51, 583},    // s=3
    {256, -64, -136, 583},    // s=4
    {2313, 229, 11, 583},     // s=5
    {360, -108, 14, 583},     // s=6
    {1063, -139, -139, 583},  // s=7
    {512, 128, 64, 583},      // s=8
    {225, 21, -125, 583},     // s=9
    {-1464, -140, -122, 583}, // s=10
    {4487, 245, 85, 583},     // s=11
    {4032, 0, 0, 583},        // s=12
    {4289, -75, -189, 583},   // s=13
    {1672, 84, 102, 583},     // s=14
    {1791, -27, -51, 583},    // s=15
    {832, -64, -136, 583},    // s=16
    {2889, 229, 11, 583},     // s=17
    {360, -108, 14, 583},     // s=18
    {1639, -139, -139, 583},  // s=19
    {1088, 128, 64, 583},     // s=20
    {801, 21, -125, 583},     // s=21
    {-1464, -140, -122, 583}, // s=22
    {455, 245, 85, 583}       // s=23
};

// Fibonacci mod 24 table (Pisano period = 24)
int fib_mod24[25];
void init_fib_mod24() {
    fib_mod24[0] = 0; fib_mod24[1] = 1;
    for (int i = 2; i < 25; i++)
        fib_mod24[i] = (fib_mod24[i-1] + fib_mod24[i-2]) % 24;
}

// =====================================================================
// Build 14x14 transition matrix
// State: [u^3, u^2v, uv^2, v^3, u^2, uv, v^2, u, v, 1,
//         sum_u^3, sum_u^2, sum_u, sum_1]
// Transition: u' = a*u + b*v, v' = c*u + d*v
// =====================================================================

Matrix build_transition(ll a, ll b, ll c, ll d) {
    Matrix T(14, vector<ll>(14, 0));

    // Degree-3 monomials
    T[0][0] = mmod((lll)a*a*a);
    T[0][1] = mmod((lll)3*a*a*b);
    T[0][2] = mmod((lll)3*a*b*b);
    T[0][3] = mmod((lll)b*b*b);

    T[1][0] = mmod((lll)a*a*c);
    T[1][1] = mmod((lll)a*a*d + (lll)2*a*b*c);
    T[1][2] = mmod((lll)2*a*b*d + (lll)b*b*c);
    T[1][3] = mmod((lll)b*b*d);

    T[2][0] = mmod((lll)a*c*c);
    T[2][1] = mmod((lll)2*a*c*d + (lll)b*c*c);
    T[2][2] = mmod((lll)a*d*d + (lll)2*b*c*d);
    T[2][3] = mmod((lll)b*d*d);

    T[3][0] = mmod((lll)c*c*c);
    T[3][1] = mmod((lll)3*c*c*d);
    T[3][2] = mmod((lll)3*c*d*d);
    T[3][3] = mmod((lll)d*d*d);

    // Degree-2 monomials
    T[4][4] = mmod((lll)a*a); T[4][5] = mmod((lll)2*a*b); T[4][6] = mmod((lll)b*b);
    T[5][4] = mmod((lll)a*c); T[5][5] = mmod((lll)a*d+(lll)b*c); T[5][6] = mmod((lll)b*d);
    T[6][4] = mmod((lll)c*c); T[6][5] = mmod((lll)2*c*d); T[6][6] = mmod((lll)d*d);

    // Degree-1
    T[7][7] = a; T[7][8] = b;
    T[8][7] = c; T[8][8] = d;

    // Constant
    T[9][9] = 1;

    // Accumulators: Su3' = Su3 + u'^3, etc.
    for (int j = 0; j < 4; j++) T[10][j] = T[0][j];
    T[10][10] = 1;

    for (int j = 4; j < 7; j++) T[11][j] = T[4][j];
    T[11][11] = 1;

    T[12][7] = T[7][7]; T[12][8] = T[7][8];
    T[12][12] = 1;

    T[13][9] = 1; T[13][13] = 1;

    return T;
}

// =====================================================================
// Main solver
// =====================================================================

ll solve(ll K) {
    init_fib_mod24();

    // Fibonacci constants: F_23=28657, F_24=46368, F_25=75025
    // Transition: u' = F23*u + F24*v, v' = F24*u + F25*v
    const ll F23 = 28657, F24 = 46368, F25 = 75025;

    Matrix T = build_transition(F23, F24, F24, F25);

    // Small Fibonacci values for initial conditions
    ll fib_small[30];
    fib_small[0] = 0; fib_small[1] = 1;
    for (int i = 2; i < 30; i++)
        fib_small[i] = fib_small[i-1] + fib_small[i-2];

    ll total_288 = 0;

    for (int r = 0; r < 24; r++) {
        int s = fib_mod24[r];
        Poly& poly = POLYS[s];

        // Polynomial coefficients mod WORK_MOD (handle negative values)
        ll D_c = mmod(poly.D);
        ll C_c = mmod(poly.C);
        ll B_c = mmod(poly.B);
        ll A_c = mmod(poly.A);

        // Index range for k = 24*i + r, with k in [2, K]
        ll i_min = (r >= 2) ? 0 : 1;

        // IMPORTANT: guard against negative (K - r) before division
        if (K < r) continue;
        ll i_max = (K - r) / 24;

        if (i_max < i_min) continue;
        ll n_terms = i_max - i_min + 1;

        // Initial Fibonacci values at k_start = 24*i_min + r
        ll k_start = 24 * i_min + r;
        ll u = fib_small[k_start] % WORK_MOD;
        ll v = fib_small[k_start + 1] % WORK_MOD;

        // Build initial state (with first term already in accumulators)
        vector<ll> state(14);
        state[0]  = mmod((lll)u*u*u);
        state[1]  = mmod((lll)u*u*v);
        state[2]  = mmod((lll)u*v*v);
        state[3]  = mmod((lll)v*v*v);
        state[4]  = mmod((lll)u*u);
        state[5]  = mmod((lll)u*v);
        state[6]  = mmod((lll)v*v);
        state[7]  = u;
        state[8]  = v;
        state[9]  = 1;
        state[10] = state[0]; // Su3 initialized with first term
        state[11] = state[4]; // Su2
        state[12] = u;        // Su
        state[13] = 1;        // count

        if (n_terms > 1) {
            Matrix T_pow = mat_pow(T, n_terms - 1);
            state = mat_vec(T_pow, state);
        }

        ll Su3 = state[10], Su2 = state[11], Su1 = state[12], S1 = state[13];

        lll contrib = (lll)A_c * Su3 + (lll)B_c * Su2
                    + (lll)C_c * Su1 + (lll)D_c * S1;
        total_288 = (total_288 + mmod(contrib)) % WORK_MOD;
    }

    return total_288 / 288;
}

// =====================================================================
// Verification
// =====================================================================

void verify() {
    printf("Verification:\n");

    // M(4,2,5) = 6
    auto M = [](int a, int b, int c) -> int {
        return __gcd(__gcd(24, 36+6*a), __gcd(14+6*a+2*b, 1+a+b+c));
    };
    assert(M(4,2,5) == 6);
    printf("  [PASS] M(4,2,5) = 6\n");

    // S(10) = 1972
    assert(S_analytical(10) == 1972);
    printf("  [PASS] S(10) = 1972\n");

    // S(10000) = 2024258331114
    assert(S_analytical(10000) == 2024258331114LL);
    printf("  [PASS] S(10000) = 2024258331114\n");

    // Cross-validate K=20 with brute force
    ll fib[21]; fib[0] = 0; fib[1] = 1;
    for (int i = 2; i <= 20; i++) fib[i] = fib[i-1] + fib[i-2];
    ll bf_sum = 0;
    for (int k = 2; k <= 20; k++)
        bf_sum = (bf_sum + S_analytical(fib[k]) % MOD_FINAL) % MOD_FINAL;
    ll mat_sum = solve(20);
    printf("  K=20 brute-force: %lld, matrix: %lld\n", bf_sum, mat_sum);
    assert(mat_sum == bf_sum);
    printf("  [PASS] K=20 cross-validation\n");
}

// =====================================================================
// Main
// =====================================================================

int main() {
    printf("Project Euler Problem 402: Integer-valued Polynomials\n");
    printf("=====================================================\n\n");

    verify();
    printf("\n");

    auto t0 = chrono::steady_clock::now();
    ll answer = solve(1234567890123LL);
    auto t1 = chrono::steady_clock::now();
    double elapsed = chrono::duration<double>(t1 - t0).count();

    printf("Answer: %lld\n", answer);
    printf("Time:   %.3f s\n", elapsed);

    return 0;
}