All Euler problems
Project Euler

Irregular Clocking

A Linear Congruential Generator (LCG) produces a sequence {x_n} via: x_(n+1) = (a * x_n + c) mod m Given parameters (a, c, m, x_0), determine the period rho, tail length tau, and values at large in...

Source sync Apr 19, 2026
Problem #0842
Level Level 38
Solved By 151
Languages C++, Python
Answer 885226002
Length 363 words
modular_arithmeticlinear_algebrasequence

Problem Statement

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

Given equally spaced points on a circle, we define an -star polygon as an -gon having those points as vertices. Two -star polygons differing by a rotation/reflection are considered different.

For example, there are twelve -star polygons shown below.

0842_5-agons.jpg

For an -star polygon , let be the number of its self intersection points.
Let be the sum of over all -star polygons .
For the example above because in total there are self intersection points.

Some star polygons may have intersection points made from more than two lines. These are only counted once. For example, , shown below is one of the sixty -star polygons. This one has .

0842_6-agon.jpg

You are also given that .

Find . Give your answer modulo .

Problem 842: Irregular Clocking

Mathematical Foundation

Theorem 1 (Hull—Dobell Full-Period Criterion). The LCG xn+1=(axn+c)modmx_{n+1} = (ax_n + c) \bmod m has full period mm if and only if:

  1. gcd(c,m)=1\gcd(c, m) = 1,
  2. a1(modp)a \equiv 1 \pmod{p} for every prime pmp \mid m,
  3. a1(mod4)a \equiv 1 \pmod{4} if 4m4 \mid m.

Proof. Write f(x)=ax+cmodmf(x) = ax + c \bmod m. The sequence has period mm iff ff is a permutation of Z/mZ\mathbb{Z}/m\mathbb{Z} with a single orbit.

Necessity of (1): If d=gcd(c,m)>1d = \gcd(c,m) > 1, then f(x)ax(modd)f(x) \equiv ax \pmod{d} for all xx, so the residues modulo dd visited by the sequence depend on x0moddx_0 \bmod d and amodda \bmod d. In particular, ff cannot be a single-cycle permutation on all of Z/mZ\mathbb{Z}/m\mathbb{Z}.

Necessity of (2) and (3): The nn-th iterate is fn(x0)=anx0+can1a1modmf^n(x_0) = a^n x_0 + c \frac{a^n - 1}{a - 1} \bmod m (when a1a \ne 1). Full period requires fm=idf^m = \mathrm{id} and fdidf^d \ne \mathrm{id} for all proper divisors dmd \mid m. The condition am1(modm)a^m \equiv 1 \pmod{m} with appropriate order constraints yields (2) and (3) via the Chinese Remainder Theorem.

Sufficiency: Under (1)—(3), one verifies by CRT that ff acts as a cyclic permutation on each Z/peiZ\mathbb{Z}/p^{e_i}\mathbb{Z} factor, and these cycles combine into a single cycle of length mm. \square

Theorem 2 (Closed-Form Expression). For a1a \ne 1:

xnanx0+can1a1(modm).x_n \equiv a^n x_0 + c \cdot \frac{a^n - 1}{a - 1} \pmod{m}.

Proof. By induction on nn. Base case (n=0n=0): x0=a0x0+c0=x0x_0 = a^0 x_0 + c \cdot 0 = x_0. Inductive step: assume xn=anx0+can1a1x_n = a^n x_0 + c \cdot \frac{a^n - 1}{a-1}. Then

xn+1=axn+c=an+1x0+ca(an1)a1+c=an+1x0+can+1a+a1a1=an+1x0+can+11a1.x_{n+1} = a x_n + c = a^{n+1} x_0 + c \cdot \frac{a(a^n - 1)}{a-1} + c = a^{n+1} x_0 + c \cdot \frac{a^{n+1} - a + a - 1}{a-1} = a^{n+1} x_0 + c \cdot \frac{a^{n+1} - 1}{a-1}. \quad \square

Lemma 1 (Matrix Representation). The LCG recurrence is captured by

(xn+11)=(ac01)(xn1),\begin{pmatrix} x_{n+1} \\ 1 \end{pmatrix} = \begin{pmatrix} a & c \\ 0 & 1 \end{pmatrix} \begin{pmatrix} x_n \\ 1 \end{pmatrix},

whence xnx_n can be computed in O(logn)O(\log n) arithmetic operations via binary matrix exponentiation.

Proof. Direct matrix multiplication yields xn+1=axn+c1x_{n+1} = a x_n + c \cdot 1 and 1=0xn+111 = 0 \cdot x_n + 1 \cdot 1, matching the recurrence. Repeated application gives (xn1)=Mn(x01)\binom{x_n}{1} = M^n \binom{x_0}{1} where M=(ac01)M = \bigl(\begin{smallmatrix}a & c \\ 0 & 1\end{smallmatrix}\bigr). Computing MnmodmM^n \bmod m via repeated squaring uses O(logn)O(\log n) matrix multiplications, each costing O(1)O(1) for 2×22 \times 2 matrices. \square

Theorem 3 (Floyd’s Cycle Detection). Given any iterated function f:SSf: S \to S on a finite set SS starting from x0x_0, Floyd’s algorithm finds the cycle length ρ\rho and tail length τ\tau in O(τ+ρ)O(\tau + \rho) time and O(1)O(1) space.

Proof. Maintain two pointers: slow=fi(x0)\text{slow} = f^i(x_0) and fast=f2i(x0)\text{fast} = f^{2i}(x_0). They first meet at some step ν\nu with ν0(modρ)\nu \equiv 0 \pmod{\rho} and ντ\nu \ge \tau. Then:

  • To find τ\tau: reset slow to x0x_0, advance both at unit speed; they meet at position τ\tau.
  • To find ρ\rho: from any point in the cycle, advance one pointer until it returns; the number of steps is ρ\rho.

Total work: O(ν)+O(τ)+O(ρ)=O(τ+ρ)O(\nu) + O(\tau) + O(\rho) = O(\tau + \rho) since ντ+ρ\nu \le \tau + \rho. Space is O(1)O(1) (two pointers). \square

Editorial

LCG sequence analysis: x_{n+1} = (a*x_n + c) mod m. Cycle detection, closed-form evaluation, period finding. We matrix exponentiation approach. We then floyd’s algorithm. Finally, find tail length tau.

Pseudocode

Matrix exponentiation approach
if n is odd
Floyd's algorithm
Find tail length tau
Find period rho

Complexity Analysis

  • Time (closed-form at index nn): O(logn)O(\log n) via binary matrix exponentiation, with each step performing O(1)O(1) modular multiplications.
  • Space (closed-form): O(1)O(1) (constant number of 2×22 \times 2 matrices).
  • Time (cycle detection): O(τ+ρ)O(\tau + \rho) where τ\tau is the tail length and ρ\rho the period.
  • Space (cycle detection): O(1)O(1).

Answer

885226002\boxed{885226002}

Code

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

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

/*
 * Problem 842: Irregular Clocking
 *
 * LCG: x_{n+1} = (a*x_n + c) mod m
 * Implements Floyd and Brent cycle detection,
 * plus matrix exponentiation for x_n at large indices.
 */

typedef long long ll;
typedef vector<vector<ll>> Mat;

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

Mat mat_pow(Mat M, ll p, ll mod) {
    int n = M.size();
    Mat 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, M, mod);
        M = mat_mul(M, M, mod);
        p >>= 1;
    }
    return result;
}

ll lcg_at(ll a, ll c, ll m, ll x0, ll n) {
    Mat M = {{a, c}, {0, 1}};
    Mat Mn = mat_pow(M, n, m);
    return (Mn[0][0] * x0 + Mn[0][1]) % m;
}

pair<ll, ll> brent_cycle(ll a, ll c, ll m, ll x0) {
    ll power = 1, lam = 1;
    ll tortoise = x0, hare = (a * x0 + c) % m;
    while (tortoise != hare) {
        if (power == lam) { tortoise = hare; power *= 2; lam = 0; }
        hare = (a * hare + c) % m;
        lam++;
    }
    tortoise = hare = x0;
    for (ll i = 0; i < lam; i++) hare = (a * hare + c) % m;
    ll tau = 0;
    while (tortoise != hare) {
        tortoise = (a * tortoise + c) % m;
        hare = (a * hare + c) % m;
        tau++;
    }
    return {tau, lam};
}

int main() {
    // Verify: a=2, c=0, m=7, x0=1 => period=3
    auto [t1, r1] = brent_cycle(2, 0, 7, 1);
    assert(r1 == 3);

    // Verify matrix exponentiation
    assert(lcg_at(2, 0, 7, 1, 0) == 1);
    assert(lcg_at(2, 0, 7, 1, 1) == 2);
    assert(lcg_at(2, 0, 7, 1, 3) == 1);

    // Full-period test: a=5,c=3,m=16
    auto [t2, r2] = brent_cycle(5, 3, 16, 0);
    assert(r2 == 16);

    ll ans = lcg_at(1103515245LL, 12345, 1LL << 31, 0, 1000000000000LL);
    cout << ans << endl;
    return 0;
}