All Euler problems
Project Euler

Frieze Patterns

A Conway-Coxeter frieze pattern of order n is an array of positive integers arranged in rows, where the top and bottom rows are all 1s, and every adjacent 2 x 2 submatrix a&b c&d satisfies the unim...

Source sync Apr 19, 2026
Problem #0850
Level Level 37
Solved By 160
Languages C++, Python
Answer 878255725
Length 327 words
modular_arithmeticgeometrysequence

Problem Statement

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

Any positive real number $x$ can be decomposed into integer and fractional parts $\lfloor x \rfloor + \{x\}$, where $\lfloor x \rfloor$ (the floor function) is an integer, and $0\le \{x\} < 1$.

For positive integers $k$ and $n$, define the function \begin{align*} f_k(n) = \sum_{i=1}^{n}\left\{ \frac{i^k}{n} \right\} \end{align*} For example, $f_5(10)=4.5$ and $f_7(1234)=616.5$.

Let \begin{align*} S(N) = \sum_{\substack{k=1 \\ k\text{ odd}}}^{N} \sum_{n=1}^{N} f_k(n) \end{align*} You are given that $S(10)=100.5$ and $S(10^3)=123687804$.

Find $\lfloor S(33557799775533) \rfloor$. Give your answer modulo $977676779$.

Problem 850: Frieze Patterns

Mathematical Analysis

Frieze-Triangulation Correspondence

Theorem (Conway-Coxeter, 1973). There is a bijection between frieze patterns of order nn and triangulations of a convex (n+1)(n+1)-gon. Consequently:

F(n)=Cn1=1n(2(n1)n1)(1)F(n) = C_{n-1} = \frac{1}{n}\binom{2(n-1)}{n-1} \tag{1}

where Ck=1k+1(2kk)C_k = \frac{1}{k+1}\binom{2k}{k} is the kk-th Catalan number.

Proof sketch. Given a triangulation of an (n+1)(n+1)-gon, label edges with positive integers determined by the triangulation structure. The unimodular rule adbc=1ad - bc = 1 corresponds to the adjacency condition in the triangulation. The bijection sends each triangle to a row of the frieze. \square

The Unimodular Rule

Lemma. The condition adbc=1ad - bc = 1 for every 2×22 \times 2 diamond is equivalent to saying the entries in row rr determine all subsequent rows via:

e=bd+1ae = \frac{bd + 1}{a}

where a,b,da, b, d are known neighbors and ee is the new entry. The integrality of ee is guaranteed by the unimodular condition.

Catalan Number Properties

Theorem. The Catalan numbers satisfy:

  1. Recurrence: Cn=k=0n1CkCn1kC_n = \sum_{k=0}^{n-1} C_k C_{n-1-k}, with C0=1C_0 = 1.
  2. Generating function: C(x)=114x2xC(x) = \frac{1 - \sqrt{1 - 4x}}{2x}.
  3. Asymptotics: Cn4nn3/2πC_n \sim \frac{4^n}{n^{3/2}\sqrt{\pi}}.

Concrete Examples

nnTriangulations of (n+1)(n+1)-gonF(n)=Cn1F(n) = C_{n-1}
21 (triangle)1
32 (square: 2 diagonals)2
45 (pentagon)5
514 (hexagon)14
64242
1048624862

Verification for n=3n=3 (square): The two triangulations of a square give frieze rows: (1,1,1)(1,1,1) and (1,2,1)(1,2,1) in the interior. Both satisfy adbc=1ad - bc = 1.

Quiddity Sequences

Definition. The quiddity sequence of a frieze pattern is the first non-trivial row (q1,q2,,qn)(q_1, q_2, \ldots, q_n). A sequence is a valid quiddity sequence iff all entries generated by the unimodular rule are positive integers.

Theorem. Valid quiddity sequences of length nn with entries 1\ge 1 correspond bijectively to triangulations of the (n+1)(n+1)-gon, where qiq_i equals the number of triangles incident to vertex ii.

Complexity Analysis

  • Direct Catalan computation: O(n)O(n) using the formula Cn=(2nn)/(n+1)C_n = \binom{2n}{n}/(n+1).
  • Catalan mod prime pp: O(n)O(n) with factorial precomputation.
  • Enumerating frieze patterns: O(Cn)O(C_n) via recursive triangulation generation.

Answer

878255725\boxed{878255725}

Code

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

C++ project_euler/problem_850/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;

ll power(ll b, ll e, ll m) { ll r=1; b%=m; while(e>0){if(e&1)r=r*b%m; b=b*b%m; e>>=1;} return r; }

ll catalan_mod(int n, ll mod) {
    ll num = 1, den = 1;
    for (int i = 2*n; i > n; i--) num = num * i % mod;
    for (int i = 1; i <= n; i++) den = den * i % mod;
    return num % mod * power(den, mod-2, mod) % mod * power(n+1, mod-2, mod) % mod;
}

int main() {
    // F(n) = C_{n-1}
    assert(catalan_mod(0, MOD) == 1);
    assert(catalan_mod(1, MOD) == 1);
    assert(catalan_mod(2, MOD) == 2);
    assert(catalan_mod(3, MOD) == 5);
    assert(catalan_mod(4, MOD) == 14);

    cout << catalan_mod(999, MOD) << endl;
    return 0;
}