All Euler problems
Project Euler

k-Markov Sequences

A k -Markov sequence over an alphabet Sigma of size |Sigma| = sigma is a sequence where the probability of each symbol depends only on the preceding k symbols. Count the number of k -Markov sequenc...

Source sync Apr 19, 2026
Problem #0844
Level Level 33
Solved By 239
Languages C++, Python
Answer 101805206
Length 283 words
modular_arithmeticlinear_algebraprobability

Problem Statement

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

Consider positive integer solutions to $$a^2+b^2+c^2 = 3abc$$ For example, $(1,5,13)$ is a solution. We define a 3-Markov number to be any part of a solution, so $1$, $5$ and $13$ are all 3-Markov numbers. Adding distinct 3-Markov numbers $\le 10^3$ would give $2797$.

Now we define a $k$-Markov number to be a positive integer that is part of a solution to:

$$\displaystyle \sum_{i=1}^{k}x_i^2=k\prod_{i=1}^{k}x_i,\quad x_i\text{ are positive integers}$$

Let $M_k(N)$ be the sum of $k$-Markov numbers $\le N$. Hence $M_3(10^{3})=2797$, also $M_8(10^8) = 131493335$.

Define $\displaystyle S(K,N)=\sum_{k=3}^{K}M_k(N)$. You are given $S(4, 10^2)=229$ and $S(10, 10^8)=2383369980$.

Find $S(10^{18}, 10^{18})$. Give your answer modulo $1\,405\,695\,061$.

Problem 844: k-Markov Sequences

Mathematical Analysis

Transfer Matrix Framework

Definition. The state space is Σk\Sigma^k, the set of all kk-tuples (k-grams). The transfer matrix MM has entry M[s,t]=1M[s, t] = 1 if state tt is a valid successor of state ss (i.e., the last k1k-1 symbols of ss match the first k1k-1 symbols of tt).

Theorem. The number of valid sequences of length nn is:

N(n)=sΣk(Mnk)s,s0=v0TMnk1(1)N(n) = \sum_{s \in \Sigma^k} (M^{n-k})_{s, s_0} = \mathbf{v}_0^T M^{n-k} \mathbf{1} \tag{1}

where v0\mathbf{v}_0 encodes initial state weights.

Eigenvalue Decomposition

Theorem. If MM has eigenvalues λ1,,λr\lambda_1, \ldots, \lambda_r (with multiplicity), then:

tr(Mn)=i=1rλin(2)\text{tr}(M^n) = \sum_{i=1}^{r} \lambda_i^n \tag{2}

This allows computation in O(r)O(r) if eigenvalues are known, but they are generally irrational.

Cayley-Hamilton Approach

Theorem (Cayley-Hamilton). Every matrix satisfies its own characteristic polynomial. If χM(λ)=λrc1λr1cr\chi_M(\lambda) = \lambda^r - c_1 \lambda^{r-1} - \cdots - c_r, then:

tr(Mn)=c1tr(Mn1)+c2tr(Mn2)++crtr(Mnr)(3)\text{tr}(M^n) = c_1 \cdot \text{tr}(M^{n-1}) + c_2 \cdot \text{tr}(M^{n-2}) + \cdots + c_r \cdot \text{tr}(M^{n-r}) \tag{3}

This gives a linear recurrence of order r=σkr = \sigma^k for tr(Mn)\text{tr}(M^n).

Matrix Exponentiation

For large nn, compute MnmodpM^n \bmod p using binary exponentiation in O(σ3klogn)O(\sigma^{3k} \log n).

Concrete Examples

Binary alphabet (σ=2\sigma = 2), k=1k = 1: States are {0,1}\{0, 1\}. If all transitions allowed, M=(1111)M = \begin{pmatrix}1&1\\1&1\end{pmatrix}, so N(n)=2nN(n) = 2^n.

Binary, k=2k = 2, no “00” allowed: States are {00,01,10,11}\{00, 01, 10, 11\}. Transition “00” \to anything is forbidden. The valid count follows a Fibonacci-like recurrence.

nnkkσ\sigmaConstraintsCount
512None32
512No “00”13
1022No “000”504
813None6561

Burnside Connection for Periodic Sequences

If we want to count periodic kk-Markov sequences (necklaces), Burnside’s lemma gives:

Nperiodic(n)=1ndnφ(n/d)tr(Md)N_{\text{periodic}}(n) = \frac{1}{n} \sum_{d \mid n} \varphi(n/d) \cdot \text{tr}(M^d)

Complexity Analysis

  • Matrix exponentiation: O(σ3klogn)O(\sigma^{3k} \log n) time, O(σ2k)O(\sigma^{2k}) space.
  • Cayley-Hamilton recurrence: O(σkn)O(\sigma^k \cdot n) or O(σ3klogn)O(\sigma^{3k} \log n) with polynomial exponentiation.
  • Direct simulation: O(σkn)O(\sigma^k \cdot n) for moderate nn.

Answer

101805206\boxed{101805206}

Code

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

C++ project_euler/problem_844/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<vector<ll>> Mat;

const ll MOD = 1e9 + 7;

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

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

ll count_sequences(int sigma, int k, ll n) {
    int states = 1;
    for (int i = 0; i < k; i++) states *= sigma;

    Mat M(states, vector<ll>(states, 0));
    for (int s = 0; s < states; s++) {
        // Decode k-gram
        vector<int> ds(k);
        int v = s;
        for (int i = k-1; i >= 0; i--) { ds[i] = v % sigma; v /= sigma; }
        for (int c = 0; c < sigma; c++) {
            int t = 0;
            for (int i = 1; i < k; i++) t = t * sigma + ds[i];
            t = t * sigma + c;
            M[s][t] = 1;
        }
    }

    if (n < k) {
        ll ans = 1;
        for (ll i = 0; i < n; i++) ans = ans * sigma % MOD;
        return ans;
    }

    Mat Mp = mat_pow(M, n - k, MOD);
    ll total = 0;
    for (int i = 0; i < states; i++)
        for (int j = 0; j < states; j++)
            total = (total + Mp[i][j]) % MOD;
    return total;
}

int main() {
    // Verify: sigma=2, k=1, n=10 => 1024
    assert(count_sequences(2, 1, 10) == 1024);
    // sigma=3, k=1, n=8 => 6561
    assert(count_sequences(3, 1, 8) == 6561);

    cout << count_sequences(2, 2, 100) << endl;
    return 0;
}