All Euler problems
Project Euler

Minimum of Subsequences

Define the pseudo-random sequence {S_n} by S_0 = 290797 and S_(n+1) = S_n^2 mod 50515093. Let A(i,j) = min(S_i, S_(i+1),..., S_j) for 1 <= i <= j. Compute: M(N) = sum_(1 <= i <= j <= N) A(i,j) for...

Source sync Apr 19, 2026
Problem #0375
Level Level 15
Solved By 1,027
Languages C++, Python
Answer 7435327983715286168
Length 391 words
modular_arithmeticoptimizationsequence

Problem Statement

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

Let \(S_n\) be an integer sequence produced with the following pseudo-random number generator: \begin {align*} S_0 & = 290797 \\ S_{n+1} & = S_n^2 \bmod 50515093 \end {align*}

Let \(A(i, j)\) be the minimum of the numbers \(S_i, S_{i+1}, \dots , S_j\) for \(i\le j\).

Let \(M(N) = \sum A(i, j)\) for \(1 \le i \le j \le N\).

We can verify that \(M(10) = 432256955\) and \(M(10\,000) = 3264567774119\).

Find \(M(2\,000\,000\,000)\).

Problem 375: Minimum of Subsequences

Mathematical Foundation

Theorem (Incremental Decomposition). Define R(j)=i=1jA(i,j)R(j) = \sum_{i=1}^{j} A(i,j). Then M(N)=j=1NR(j)M(N) = \sum_{j=1}^{N} R(j), and the sequence {R(j)}\{R(j)\} satisfies the recurrence:

R(j+1)=R(j)(v,c) poppedvc+Sj+1(ctotal+1)R(j+1) = R(j) - \sum_{\substack{(v,c) \text{ popped}}} v \cdot c + S_{j+1} \cdot (c_{\text{total}} + 1)

where the “popped” elements are those removed from a monotone stack when inserting Sj+1S_{j+1}, and ctotalc_{\text{total}} is the total count of starting indices they collectively represented.

Proof. Consider extending all subsequences ending at position jj by one element Sj+1S_{j+1}, and adding the new singleton (j+1,j+1)(j+1, j+1). For a subsequence starting at position ii:

A(i,j+1)=min(A(i,j),  Sj+1).A(i, j+1) = \min(A(i,j),\; S_{j+1}).

If A(i,j)Sj+1A(i,j) \ge S_{j+1}, then the new minimum becomes Sj+1S_{j+1}, reducing the contribution by A(i,j)Sj+1A(i,j) - S_{j+1}. If A(i,j)<Sj+1A(i,j) < S_{j+1}, the minimum is unchanged. Plus we add the singleton contribution Sj+1S_{j+1}.

The monotone stack tracks contiguous groups of starting indices sharing the same current minimum. Popping entries with value Sj+1\ge S_{j+1} replaces their contributions with Sj+1cS_{j+1} \cdot c for each popped group of count cc. \square

Lemma (Monotone Stack Invariant). Maintain a stack of pairs (v,c)(v, c) sorted in strictly increasing order of vv from bottom to top, where cc is the number of starting indices whose current minimum is vv. The invariant is:

R(j)=(v,c)stackvc.R(j) = \sum_{(v,c) \in \text{stack}} v \cdot c.

Proof. By induction on jj. Base: j=1j = 1, stack = {(S1,1)}\{(S_1, 1)\}, R(1)=S1R(1) = S_1. Inductive step: when processing Sj+1S_{j+1}, we pop all entries (v,c)(v, c) with vSj+1v \ge S_{j+1}. Their combined count ctotalc_{\text{total}} is accumulated, and a single new entry (Sj+1,ctotal+1)(S_{j+1}, c_{\text{total}} + 1) is pushed (the +1+1 accounts for the new singleton). The value R(j+1)R(j+1) equals the previous R(j)R(j) minus the popped contributions plus Sj+1(ctotal+1)S_{j+1} \cdot (c_{\text{total}} + 1), maintaining the invariant. \square

Lemma (Amortized Complexity). Each element is pushed exactly once and popped at most once, so the total number of stack operations over NN steps is at most 2N2N.

Proof. Each of the NN insertions pushes exactly one entry. An entry can only be popped once (after which it is gone). Since at most NN entries are ever pushed, at most NN pops occur. Total operations 2N\le 2N. \square

Editorial

S_0 = 290797, S_{n+1} = S_n^2 mod 50515093 A(i,j) = min(S_i, …, S_j) M(N) = sum of A(i,j) for all 1 <= i <= j <= N N = 2,000,000,000 The pseudo-random sequence has a cycle of length 6,308,948. We use a monotone stack for O(N) computation. Verification: M(10) = 432256955, M(10000) = 3264567774119 Note: Running this in Python for N=2e9 is very slow (~hours). Use the C++ solution for the full computation.

Pseudocode

    S = 290797
    stack = [] // list of (value, count) pairs
    R = 0 // current R(j)
    T = 0 // running total M(N)
    For j from 1 to N:
        S = S * S mod 50515093
        c = 0
        While stack is not empty and stack.top().value >= S:
            (v, cnt) = stack.pop()
            R -= v * cnt
            c += cnt
        stack.push((S, c + 1))
        R += S * (c + 1)
        T += R
    Return T

Complexity Analysis

  • Time: O(N)O(N) amortized. Each element is pushed and popped at most once; generating SnS_n is O(1)O(1) per step.
  • Space: O(N)O(N) worst case for the stack (if the sequence is strictly increasing). In practice, O(N)O(\sqrt{N}) expected for random-like sequences.

Note: RR fits in a 64-bit integer (5×1016\sim 5 \times 10^{16}), but TT can reach 1026\sim 10^{26}, requiring 128-bit or arbitrary-precision integers.

Answer

7435327983715286168\boxed{7435327983715286168}

Code

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

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

/*
 * Problem 375: Minimum of Subsequences
 *
 * S_0 = 290797, S_{n+1} = S_n^2 mod 50515093
 * M(N) = sum of min(S_i,...,S_j) for all 1 <= i <= j <= N
 * Compute M(2,000,000,000).
 *
 * The sequence has a cycle of length L=6308948 starting from index 1.
 * So S_n = S_{1 + ((n-1) mod L)} for n >= 1.
 *
 * N = 2e9: we have full_cycles = N / L and remainder = N % L.
 * 2000000000 / 6308948 = 317 full cycles with remainder.
 *
 * Strategy: use the monotone stack approach but exploit the periodicity.
 * After processing one full cycle, the stack state and running sums
 * can be used to compute subsequent cycles efficiently.
 *
 * However, the stack state at the end of each cycle may differ.
 * A simpler approach: since N/L ~ 317, we process 317+ cycles sequentially,
 * each of ~6.3M elements. Total: ~2e9 operations, feasible in C++ with O(N).
 *
 * Answer: 7435327983715286168
 */

typedef long long ll;
typedef unsigned long long ull;
typedef __int128 lll;

int main(){
    const ll N = 2000000000LL;
    const ll MOD_SEQ = 50515093LL;

    // We generate the sequence on the fly and use the stack approach.
    // Total operations: O(N) = O(2e9), each operation is simple.
    // Should run in ~30-60 seconds with optimized C++.

    ll s_prev = 290797;

    // Monotone stack: use arrays for speed
    // Max stack size: bounded by N but practically much smaller
    static ll stk_val[7000000]; // values
    static ll stk_cnt[7000000]; // counts
    int stk_top = 0;

    lll T = 0;
    ll R = 0;

    for (ll j = 1; j <= N; j++) {
        ll s_cur = (s_prev * s_prev) % MOD_SEQ;
        s_prev = s_cur;

        ll cnt = 1;
        while (stk_top > 0 && stk_val[stk_top - 1] >= s_cur) {
            stk_top--;
            R -= stk_val[stk_top] * stk_cnt[stk_top];
            cnt += stk_cnt[stk_top];
        }
        R += s_cur * cnt;
        stk_val[stk_top] = s_cur;
        stk_cnt[stk_top] = cnt;
        stk_top++;

        T += R;
    }

    // Print __int128
    ll val = (ll)T;
    if (T == (lll)val) {
        printf("%lld\n", val);
    } else {
        // T might be larger than ll max
        ull uT = (ull)T;
        // Actually for this problem T fits in signed long long based on expected answer
        // But let's be safe
        ll hi = (ll)(T / 1000000000000000000LL);
        ll lo = (ll)(T % 1000000000000000000LL);
        if (hi > 0) printf("%lld%018lld\n", hi, lo);
        else printf("%lld\n", lo);
    }

    return 0;
}