All Euler problems
Project Euler

Summation of Summations

Define the m -fold iterated partial sum of a sequence (a_1, a_2,..., a_n) by S^((m))_n = sum_(i_1=1)^n sum_(i_2=1)^(i_1)... sum_(i_m=1)^i_(m-1) a_(i_m). Find a closed-form expression for S^((m))_n...

Source sync Apr 19, 2026
Problem #0894
Level Level 27
Solved By 376
Languages C++, Python
Answer 0.7718678168
Length 239 words
linear_algebrasequencecombinatorics

Problem Statement

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

Consider a unit circle \(C_0\) on the plane that does not enclose the origin. For \(k \geq 1\), a circle \(C_k\) is created by scaling and rotating \(C_{k - 1}\) with respect to the origin. That is, both the radius and the distance to the origin are scaled by the same factor, and the centre of rotation is the origin. The scaling factor is positive and strictly less than one. Both it and the rotation angle remain constant for each \(k\).

It is given that \(C_0\) is externally tangent to \(C_1\), \(C_7\) and \(C_8\), as shown in the diagram belowm, and no two circles overlap.

PIC

Find the total area of all the circular triangles in the diagram, i.e. the are painted green above.

Give your answer rounded to \(10\) places after the decimal point.

Problem 894: Summation of Summations

Mathematical Foundation

Theorem 1 (Hockey Stick / Stars-and-Bars Reduction). For any sequence (ak)(a_k) and integers m1m \geq 1, n1n \geq 1:

Sn(m)=k=1n(nk+m1m1)ak.S^{(m)}_n = \sum_{k=1}^{n} \binom{n - k + m - 1}{m - 1}\, a_k.

Proof. The element aka_k appears in Sn(m)S^{(m)}_n once for each weakly increasing chain kimim1i1nk \leq i_m \leq i_{m-1} \leq \cdots \leq i_1 \leq n. Setting j=ikj_\ell = i_\ell - k for =m\ell = m and j=ii+1j_\ell = i_\ell - i_{\ell+1} for <m\ell < m, we obtain nonneg integers j1,,jm10j_1, \ldots, j_{m-1} \geq 0 with the constraint j1+j2++jm1+(i1i1)nkj_1 + j_2 + \cdots + j_{m-1} + (i_1 - i_1) \leq n - k. More precisely, the chain is equivalent to choosing m1m - 1 nonneg integers summing to at most nkn - k, which by a standard stars-and-bars argument yields

((nk)+(m1)m1)=(nk+m1m1)\binom{(n - k) + (m - 1)}{m - 1} = \binom{n - k + m - 1}{m - 1}

chains. \square

Theorem 2 (Matrix Formulation). Let LL be the n×nn \times n lower-triangular matrix with Lij=[ij]L_{ij} = [i \geq j]. Then Sn(m)=(Lma)nS^{(m)}_n = (L^m \mathbf{a})_n, and (Lm)ij=(ij+m1m1)(L^m)_{ij} = \binom{i - j + m - 1}{m - 1} for iji \geq j.

Proof. We proceed by induction on mm. For m=1m = 1, (La)i=j=1iaj=Si(1)(L\mathbf{a})_i = \sum_{j=1}^{i} a_j = S^{(1)}_i and (L1)ij=[ij]=(ij0)(L^1)_{ij} = [i \geq j] = \binom{i-j}{0}. Assuming (Lm)ij=(ij+m1m1)(L^m)_{ij} = \binom{i-j+m-1}{m-1}, we compute

(Lm+1)ij==ji(L)i(Lm)j==ji(j+m1m1)=(ij+mm),(L^{m+1})_{ij} = \sum_{\ell=j}^{i} (L)_{i\ell} \cdot (L^m)_{\ell j} = \sum_{\ell=j}^{i} \binom{\ell - j + m - 1}{m - 1} = \binom{i - j + m}{m},

where the last step applies the hockey stick identity r=0s(r+m1m1)=(s+mm)\sum_{r=0}^{s}\binom{r+m-1}{m-1} = \binom{s+m}{m}. \square

Lemma (Special Cases).

  • For ak=1a_k = 1: Sn(m)=(n+m1m)S^{(m)}_n = \binom{n+m-1}{m}.
  • For ak=ka_k = k: Sn(m)=(n+mm+1)S^{(m)}_n = \binom{n+m}{m+1}.

Proof. For ak=1a_k = 1: Sn(m)=k=1n(nk+m1m1)=j=0n1(j+m1m1)=(n+m1m)S^{(m)}_n = \sum_{k=1}^{n}\binom{n-k+m-1}{m-1} = \sum_{j=0}^{n-1}\binom{j+m-1}{m-1} = \binom{n+m-1}{m} by the hockey stick identity.

For ak=ka_k = k: Sn(m)=k=1nk(nk+m1m1)S^{(m)}_n = \sum_{k=1}^{n} k\binom{n-k+m-1}{m-1}. Using the identity k(nk+m1m1)=n(nk+m1m1)(nk)(nk+m1m1)k\binom{n-k+m-1}{m-1} = n\binom{n-k+m-1}{m-1} - (n-k)\binom{n-k+m-1}{m-1} and the absorption identity (nk)(nk+m1m1)=m(nk+m1m)(n-k)\binom{n-k+m-1}{m-1} = m\binom{n-k+m-1}{m}… Alternatively, note that Sn(1)=n(n+1)/2=(n+12)S^{(1)}_n = n(n+1)/2 = \binom{n+1}{2} for ak=ka_k = k, and applying LL repeatedly, Sn(m)=(n+mm+1)S^{(m)}_n = \binom{n+m}{m+1} follows by induction using the hockey stick identity. \square

Editorial

m-fold iterated partial sum: S^(m)_n = sum_k C(n-k+m-1, m-1) * a_k Special case a_k = k: S^(m)_n = C(n+m, m+1). We o(n) computation using Theorem 1. We then compute binomial coefficients incrementally. Finally, update: binom(n-k+m-1, m-1) -> binom(n-(k-1)+m-1, m-1).

Pseudocode

O(n) computation using Theorem 1
Compute binomial coefficients incrementally
Update: binom(n-k+m-1, m-1) -> binom(n-(k-1)+m-1, m-1)
O(mn) computation via m passes of prefix sums

Complexity Analysis

  • Time (closed-form method): O(n)O(n) — single pass with incremental binomial coefficient updates.
  • Space (closed-form method): O(1)O(1) beyond the input array.
  • Time (prefix sum method): O(mn)O(mn)mm passes of prefix summation.
  • Space (prefix sum method): O(n)O(n) for the working array.
  • Time (naive nested loops): O(nm)O(n^m).
  • Space (naive nested loops): O(1)O(1).

Answer

0.7718678168\boxed{0.7718678168}

Code

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

C++ project_euler/problem_894/solution.cpp
/*
 * Problem 894: Summation of Summations
 * m-fold iterated partial sum: S^(m)_n = sum_k C(n-k+m-1, m-1) * a_k.
 * For a_k = k: S^(m)_n = C(n+m, m+1).
 * Three approaches: nested loops O(n^m), prefix sums O(mn), closed form O(n).
 */
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll comb(ll n, ll r) {
    if (r < 0 || r > n) return 0;
    if (r > n - r) r = n - r;
    ll result = 1;
    for (ll i = 0; i < r; i++) {
        result = result * (n - i) / (i + 1);
    }
    return result;
}

// Method 1: Direct nested loops for m=3
ll triple_sum_brute(const vector<ll>& a) {
    int n = a.size();
    ll total = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j <= i; j++)
            for (int k = 0; k <= j; k++)
                total += a[k];
    return total;
}

// Method 2: Prefix sum applied m times
ll iterated_prefix(vector<ll> a, int m) {
    int n = a.size();
    for (int step = 0; step < m; step++)
        for (int i = 1; i < n; i++)
            a[i] += a[i - 1];
    return a[n - 1];
}

// Method 3: Closed-form weighted sum
ll closed_form(const vector<ll>& a, int m) {
    int n = a.size();
    ll total = 0;
    for (int k = 0; k < n; k++) {
        ll weight = comb(n - 1 - k + m - 1, m - 1);
        total += weight * a[k];
    }
    return total;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // Verification: a_k = k, m = 3
    cout << "=== Triple Summation (m=3, a_k=k) ===" << endl;
    for (int n = 1; n <= 10; n++) {
        vector<ll> a(n);
        for (int i = 0; i < n; i++) a[i] = i + 1;
        ll b = triple_sum_brute(a);
        ll p = iterated_prefix(a, 3);
        ll c = closed_form(a, 3);
        ll identity = comb(n + 3, 4);
        cout << "n=" << setw(2) << n
             << ": brute=" << setw(6) << b
             << " prefix=" << setw(6) << p
             << " formula=" << setw(6) << c
             << " C(n+3,4)=" << setw(6) << identity
             << (b == p && p == c && c == identity ? " OK" : " FAIL") << endl;
        assert(b == p && p == c && c == identity);
    }

    // General m verification
    cout << "\n=== Various m (a_k=k, n=10) ===" << endl;
    int n = 10;
    vector<ll> a(n);
    for (int i = 0; i < n; i++) a[i] = i + 1;
    for (int m = 1; m <= 6; m++) {
        ll prefix = iterated_prefix(a, m);
        ll formula = closed_form(a, m);
        ll identity = comb(n + m, m + 1);
        cout << "m=" << m << ": prefix=" << prefix
             << " formula=" << formula
             << " C(n+m,m+1)=" << identity
             << (prefix == formula && formula == identity ? " OK" : " FAIL") << endl;
    }

    // Large computation
    ll ans = comb(10003, 4);
    cout << "\nS^(3)_{10000} for a_k=k = C(10003,4) = " << ans << endl;
    cout << "\nAnswer: " << ans << endl;

    return 0;
}