Open Source · 7 Languages · 900+ Problems

Project Euler Solutions

Complete solutions in C++, Python & Java — with step-by-step mathematical explanations

All Problems

Problem 435: Polynomials of Fibonacci Numbers

View on Project Euler

Project Euler Problem 435 Solution

EulerSolve provides an optimized solution for Project Euler Problem 435, Polynomials of Fibonacci Numbers, with C++, Python, Java, and a step-by-step mathematical explanation.

Problem Summary Let the Fibonacci numbers be \(f_0=0\), \(f_1=1\), and \(f_n=f_{n-1}+f_{n-2}\). For each integer \(x\), define the truncated polynomial $F_n(x)=\sum_{k=0}^{n} f_k x^k.$ The task is to evaluate $\sum_{x=0}^{100} F_n(x) \pmod{15!}$ for the enormous index \(n=10^{15}\). A direct loop over all Fibonacci terms is impossible, so the key is to turn the polynomial sum into a fixed-size linear recurrence that can be exponentiated in logarithmic time. Mathematical Approach Step 1: Isolate the weighted Fibonacci term For a fixed value of \(x\), define $a_k=f_k x^k.$ Using the Fibonacci recurrence, $a_{k+1}=f_{k+1}x^{k+1}=(f_k+f_{k-1})x^{k+1}=x a_k + x^2 a_{k-1}.$ So once \(x\) is fixed, the sequence \(a_k\) satisfies a second-order linear recurrence with constant coefficients \(x\) and \(x^2\). Step 2: Add the partial sum to the state vector The polynomial value itself is the prefix sum of the \(a_k\): $F_k(x)=\sum_{i=0}^{k} a_i.$ Therefore $F_{k+1}(x)=F_k(x)+a_{k+1}.$ Now combine the recurrence for \(a_k\) with the update for the running sum....

Detailed mathematical approach

Problem Summary

Let the Fibonacci numbers be \(f_0=0\), \(f_1=1\), and \(f_n=f_{n-1}+f_{n-2}\). For each integer \(x\), define the truncated polynomial

$F_n(x)=\sum_{k=0}^{n} f_k x^k.$

The task is to evaluate

$\sum_{x=0}^{100} F_n(x) \pmod{15!}$

for the enormous index \(n=10^{15}\). A direct loop over all Fibonacci terms is impossible, so the key is to turn the polynomial sum into a fixed-size linear recurrence that can be exponentiated in logarithmic time.

Mathematical Approach

Step 1: Isolate the weighted Fibonacci term

For a fixed value of \(x\), define

$a_k=f_k x^k.$

Using the Fibonacci recurrence,

$a_{k+1}=f_{k+1}x^{k+1}=(f_k+f_{k-1})x^{k+1}=x a_k + x^2 a_{k-1}.$

So once \(x\) is fixed, the sequence \(a_k\) satisfies a second-order linear recurrence with constant coefficients \(x\) and \(x^2\).

Step 2: Add the partial sum to the state vector

The polynomial value itself is the prefix sum of the \(a_k\):

$F_k(x)=\sum_{i=0}^{k} a_i.$

Therefore

$F_{k+1}(x)=F_k(x)+a_{k+1}.$

Now combine the recurrence for \(a_k\) with the update for the running sum. With the state vector

$v_k=\begin{bmatrix}a_k\\ a_{k-1}\\ F_k(x)\end{bmatrix},$

we obtain the linear transition

$v_{k+1}=T_x v_k,\qquad T_x=\begin{bmatrix} x & x^2 & 0\\ 1 & 0 & 0\\ x & x^2 & 1 \end{bmatrix}.$

The first row reproduces \(a_{k+1}=x a_k+x^2 a_{k-1}\), the second row shifts \(a_k\) into the next position, and the third row accumulates the new term into the polynomial sum.

Step 3: Base state and matrix power

For \(k=1\),

$a_1=f_1 x=x,\qquad a_0=f_0=0,\qquad F_1(x)=f_0+f_1 x=x.$

Hence the base vector is

$v_1=\begin{bmatrix}x\\ 0\\ x\end{bmatrix}.$

For every \(n\ge 1\),

$v_n=T_x^{\,n-1}v_1,$

and the desired value \(F_n(x)\) is the third component of \(v_n\). The special case \(n=0\) is immediate because \(F_0(x)=f_0=0\).

Step 4: Why repeated squaring is the right tool

The matrix \(T_x\) has fixed size \(3\times 3\), so its \((n-1)\)-st power can be computed by binary exponentiation in \(O(\log n)\) matrix multiplications. Every operation is performed modulo

$M=15!=1307674368000.$

This keeps the numbers bounded while matching the modulus required by the problem.

Alternative closed form and why the implementation avoids division

The truncated generating function also satisfies

$\left(1-x-x^2\right)F_n(x)=x-f_{n+1}x^{n+1}-f_n x^{n+2}.$

Over the integers this identity is correct and useful, but modulo \(15!\) the factor \(1-x-x^2\) is not always invertible. For example, at \(x=2\) it equals \(-5\), and \(5\) shares a factor with \(15!\). The matrix formulation is therefore preferable: it is division-free and works uniformly for every \(x\in\{0,\dots,100\}\).

Worked checks

Several small cases confirm the recurrence.

First, \(F_n(0)=0\) for all \(n\), because every term contains either \(f_0=0\) or a positive power of \(0\).

Second, for \(n=7\) and \(x=11\),

$F_7(11)=11+11^2+2\cdot 11^3+3\cdot 11^4+5\cdot 11^5+8\cdot 11^6+13\cdot 11^7=268357683.$

This matches the value produced by the matrix method.

A larger checkpoint is

$\sum_{x=0}^{10} F_{20}(x)\equiv 1044074802100 \pmod{15!},$

which is exactly the validation target used by the implementations.

How the Code Works

The C++, Python, and Java implementations all follow the same structure. For each \(x\in\{0,\dots,100\}\), they build the transition matrix \(T_x\), raise it to the power \(n-1\) by repeated squaring, multiply by the base vector, and read the third component as \(F_n(x)\). These 101 values are then accumulated modulo \(15!\).

Because \(15!\approx 1.3\times 10^{12}\), an unreduced product of two residues can exceed ordinary 64-bit multiplication in some languages. The implementations therefore perform modular multiplication carefully before each reduction, but the mathematical algorithm itself remains the same in all three languages.

Complexity Analysis

A \(3\times 3\) matrix multiplication has constant cost, and binary exponentiation uses \(O(\log n)\) such multiplications. Therefore each single value \(F_n(x)\) is computed in \(O(\log n)\) time and \(O(1)\) extra space. Since the outer sum runs over exactly 101 values of \(x\), the full computation is still \(O(101\log n)=O(\log n)\) with a very small constant factor, and the memory usage stays \(O(1)\).

References

  1. Problem page: https://projecteuler.net/problem=435
  2. Fibonacci numbers: Wikipedia — Fibonacci number
  3. Matrix exponentiation / exponentiation by squaring: Wikipedia — Exponentiation by squaring
  4. Generating functions for Fibonacci numbers: Wikipedia — Fibonacci number, generating function section

Mathematical approach · C++ solution · Python solution · Java solution

Previous: Problem 434 · All Project Euler solutions · Next: Problem 436

Need help with a problem? Ask me! 💡
e
✦ Euler GLM 5.2
Hi! I'm Euler. Ask me anything about Project Euler problems, math concepts, or solution approaches! 🧮