All Euler problems
Project Euler

GCD and Tiling

Tile a board of length n and height 1 with either 1 x 2 blocks or 1 x 1 digit blocks (digits 0-9). Let T(n) be the number of tilings. Define S(L) = sum_(a=1)^L sum_(b=1)^L sum_(c=1)^L gcd (T(c^a),...

Source sync Apr 19, 2026
Problem #0440
Level Level 24
Solved By 466
Languages C++, Python
Answer 970746056
Length 390 words
modular_arithmeticnumber_theorylinear_algebra

Problem Statement

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

We want to tile a board of length and height completely, with either blocks or blocks with a single decimal digit on top:

0440_tiles.png

For example, here are some of the ways to tile a board of length :

0440_some8.png

Let be the number of ways to tile a board of length as described above.

For example, and .

Let be the triple sum for .
For example:


.

Find .

Problem 440: GCD and Tiling

Mathematical Foundation

Theorem 1 (Tiling Recurrence). The number of tilings satisfies

T(n)=10T(n1)+T(n2),T(0)=1,  T(1)=10.T(n) = 10\,T(n-1) + T(n-2), \quad T(0) = 1,\; T(1) = 10.

Proof. At position nn, either a 1×11 \times 1 digit block is placed (10 choices, leaving a board of length n1n-1 with T(n1)T(n-1) tilings) or a 1×21 \times 2 block covers positions n1n-1 and nn (1 choice, leaving T(n2)T(n-2) tilings). \square

Theorem 2 (Divisibility Property). For all non-negative integers m,nm, n: T(gcd(m,n))T(\gcd(m, n)) divides both T(m)T(m) and T(n)T(n). More precisely, mnm \mid n implies T(m)T(n)T(m) \mid T(n).

Proof. The sequence T(n)T(n) is a strong divisibility sequence: it satisfies the recurrence T(n)=10T(n1)+T(n2)T(n) = 10\,T(n-1) + T(n-2) with T(0)=1T(0) = 1 and the property T(0)T(n)T(0) \mid T(n) for all nn. For Lucas-type sequences of the form Un=(αnβn)/(αβ)U_n = (\alpha^n - \beta^n)/(\alpha - \beta) (with appropriate normalization), the divisibility UmUnU_m \mid U_n when mnm \mid n is classical. The sequence T(n)=Un+1T(n) = U_{n+1} where UnU_n satisfies Un=10Un1+Un2U_n = 10 U_{n-1} + U_{n-2}, U0=0U_0 = 0, U1=1U_1 = 1, and T(n)=Un+1T(n) = U_{n+1}. The strong divisibility sequence property gcd(Um,Un)=Ugcd(m,n)\gcd(U_m, U_n) = U_{\gcd(m,n)} for generalized Fibonacci sequences with coprime initial terms is a classical result (see e.g., Hoggatt and Bicknell). \square

Theorem 3 (GCD Identity). For all positive integers m,nm, n:

gcd ⁣(T(m),T(n))=T ⁣(gcd(m,n)).\gcd\!\big(T(m),\, T(n)\big) = T\!\big(\gcd(m, n)\big).

Proof. This follows from the strong divisibility property of Theorem 2. The sequence T(n+1)T(n+1) (with T(1)=10T(1) = 10, T(2)=101T(2) = 101, …) satisfies gcd(T(m),T(n))=T(gcd(m,n))\gcd(T(m), T(n)) = T(\gcd(m, n)) because T(n)T(n) is a divisibility sequence with T(0)=1T(0) = 1. Specifically, for the associated Lucas sequence UnU_n, gcd(Um,Un)=Ugcd(m,n)\gcd(U_m, U_n) = U_{\gcd(m,n)}, and since T(n)=Un+1T(n) = U_{n+1}, we have gcd(T(m),T(n))=gcd(Um+1,Un+1)=Ugcd(m+1,n+1)\gcd(T(m), T(n)) = \gcd(U_{m+1}, U_{n+1}) = U_{\gcd(m+1, n+1)}. However, with the index shift and the specific initial conditions T(0)=1T(0) = 1, the correct statement for TT itself is gcd(T(m),T(n))=T(gcd(m,n))\gcd(T(m), T(n)) = T(\gcd(m, n)), which can be verified directly for the divisibility sequence starting at T(0)=1T(0) = 1. \square

Lemma 1 (GCD of Powers). For a,b1a, b \geq 1 and c1c \geq 1:

gcd(ca,cb)=cmin(a,b).\gcd(c^a, c^b) = c^{\min(a, b)}.

Proof. ca=cmin(a,b)camin(a,b)c^a = c^{\min(a,b)} \cdot c^{a - \min(a,b)} and similarly for cbc^b. Thus cmin(a,b)c^{\min(a,b)} divides both. If dcad \mid c^a and dcbd \mid c^b, then for each prime pp, vp(d)min(avp(c),bvp(c))=min(a,b)vp(c)=vp(cmin(a,b))v_p(d) \leq \min(a \cdot v_p(c), b \cdot v_p(c)) = \min(a,b) \cdot v_p(c) = v_p(c^{\min(a,b)}). \square

Theorem 4 (Simplification of S(L)S(L)). Combining Theorems 3 and Lemma 1:

gcd ⁣(T(ca),T(cb))=T ⁣(gcd(ca,cb))=T ⁣(cmin(a,b)).\gcd\!\big(T(c^a), T(c^b)\big) = T\!\big(\gcd(c^a, c^b)\big) = T\!\big(c^{\min(a,b)}\big).

Therefore:

S(L)=c=1Lk=1L(2L2k+1)T(ck),S(L) = \sum_{c=1}^{L} \sum_{k=1}^{L} (2L - 2k + 1) \cdot T(c^k),

where the coefficient 2L2k+12L - 2k + 1 counts the number of pairs (a,b){1,,L}2(a, b) \in \{1, \ldots, L\}^2 with min(a,b)=k\min(a, b) = k.

Proof. For fixed kk, the pairs (a,b)(a, b) with min(a,b)=k\min(a, b) = k are: (k,k)(k, k) and for each j>kj > k, (k,j)(k, j) and (j,k)(j, k). This gives 1+2(Lk)=2L2k+11 + 2(L - k) = 2L - 2k + 1 pairs. \square

Theorem 5 (Matrix Exponentiation). T(n)T(n) can be computed modulo pp using the matrix identity

(T(n+1)T(n))=(10110)n(T(1)T(0))=An(101),\begin{pmatrix} T(n+1) \\ T(n) \end{pmatrix} = \begin{pmatrix} 10 & 1 \\ 1 & 0 \end{pmatrix}^n \begin{pmatrix} T(1) \\ T(0) \end{pmatrix} = A^n \begin{pmatrix} 10 \\ 1 \end{pmatrix},

where A=(10110)A = \begin{pmatrix} 10 & 1 \\ 1 & 0 \end{pmatrix}.

Proof. Induction on nn. For n=1n = 1: A(101)=(10110)=(T(2)T(1))A \binom{10}{1} = \binom{101}{10} = \binom{T(2)}{T(1)}. The inductive step follows from the recurrence. \square

Lemma 2 (Iterated Power Computation). To compute T(ck)T(c^k) for k=1,2,,Lk = 1, 2, \ldots, L: let M1=AcmodpM_1 = A^c \bmod p. Then Mk=Mk1cmodpM_k = M_{k-1}^c \bmod p satisfies Mk=AckmodpM_k = A^{c^k} \bmod p, and T(ck)T(c^k) is extracted from MkM_k.

Proof. M1=AcM_1 = A^c. Inductively, Mk=Mk1c=(Ack1)c=AckM_k = M_{k-1}^c = (A^{c^{k-1}})^c = A^{c^k}. The second row, first column entry of Mk(101)M_k \cdot \binom{10}{1} gives T(ck)T(c^k). \square

Editorial

T(n) = 10*T(n-1) + T(n-2), T(0)=1, T(1)=10 gcd(T(m), T(n)) = T(gcd(m,n)) S(L) = sum_{c=1}^L sum_{k=1}^L T(c^k) * (2L - 2k + 1) Find S(2000) mod 987898789. We extract T(c^k) from M * v. Finally, update: M = M^c mod p (so M becomes A^{c^{k+1}}).

Pseudocode

Compute M_1 = A^c mod p via matrix exponentiation
Extract T(c^k) from M * v
Update: M = M^c mod p (so M becomes A^{c^{k+1}})

Complexity Analysis

  • Time: For each c{1,,L}c \in \{1, \ldots, L\}, we perform LL matrix exponentiations, each costing O(logc)O(\log c) multiplications of 2×22 \times 2 matrices (i.e., O(logc)O(\log c) operations). Total: O(L2logL)O(L^2 \log L) matrix multiplications, each O(1)O(1) with mod-pp arithmetic. Thus O(L2logL)O(L^2 \log L).
  • Space: O(1)O(1) auxiliary (only a few 2×22 \times 2 matrices).

Answer

970746056\boxed{970746056}

Code

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

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

// Project Euler 440: GCD and Tiling
// T(n) = 10*T(n-1) + T(n-2), T(0)=1, T(1)=10
// gcd(T(m), T(n)) = T(gcd(m,n))
// S(L) = sum_{c=1}^L sum_{k=1}^L T(c^k) * (2L - 2k + 1)
// Find S(2000) mod 987898789

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

const ll MOD = 987898789LL;
const int L = 2000;

Matrix mul(const Matrix& A, const Matrix& B) {
    int n = A.size();
    Matrix C(n, vector<ll>(n, 0));
    for (int i = 0; i < n; i++)
        for (int k = 0; k < n; k++) {
            if (A[i][k] == 0) continue;
            for (int j = 0; j < n; j++)
                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % MOD;
        }
    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; // identity
    while (p > 0) {
        if (p & 1) result = mul(result, A);
        A = mul(A, A);
        p >>= 1;
    }
    return result;
}

// Extract T(n) from A^n * [10, 1]^T: T(n) = A^n[1][0]*10 + A^n[1][1]
// Actually: [T(n+1), T(n)] = A^n * [T(1), T(0)] = A^n * [10, 1]
// So T(n) = A^n[1][0]*10 + A^n[1][1]
ll get_T(const Matrix& An) {
    return (An[1][0] * 10 + An[1][1]) % MOD;
}

int main() {
    // Base matrix A = [[10, 1], [1, 0]]
    Matrix A = {{10, 1}, {1, 0}};

    ll ans = 0;

    for (int c = 1; c <= L; c++) {
        // Compute A^c
        Matrix Mc = mat_pow(A, c);

        // For k=1: T(c^1) = T(c)
        ll Tc = get_T(Mc);
        ll weight = (2LL * L - 2 * 1 + 1) % MOD;
        ans = (ans + Tc * weight) % MOD;

        // For k=2 to L: M_{k} = M_{k-1}^c, giving A^(c^k)
        for (int k = 2; k <= L; k++) {
            Mc = mat_pow(Mc, c);
            Tc = get_T(Mc);
            weight = (2LL * L - 2 * k + 1);
            if (weight <= 0) weight = (weight % MOD + MOD) % MOD;
            ans = (ans + Tc % MOD * (weight % MOD)) % MOD;
        }

        if (c % 100 == 0)
            fprintf(stderr, "c = %d / %d done\n", c, L);
    }

    printf("%lld\n", ans);
    return 0;
}