First Sort II
Using the "first sort" algorithm from Problem 523, let E(n) be the expected number of moves to sort a uniformly random permutation of {1,..., n}. Compute E(10^18) mod (10^9 + 7).
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Consider the following algorithm for sorting a list:
Starting from the beginning of the list, check each pair of adjacent elements in turn.
If the elements are out of order:
Move the smallest element of the pair at the beginning of the list.
Restart the process from step 1.
If all pairs are in order, stop.
For example, the list $\{\,4\,1\,3\,2\,\}$ is sorted as follows:
| Step | The order of the list after each sorting step |
| 1 | $\underline{4\,1}\,3\,2$ ($4$ and $1$ are out of order so move $1$ to the front of the list) |
| 2 | $1\,\underline{4\,3}\,2$ ($4$ and $3$ are out of order so move $3$ to the front of the list) |
| 3 | $\underline{3\,1}\,4\,2$ ($3$ and $1$ are out of order so move $1$ to the front of the list) |
| 4 | $1\,3\,\underline{4\,2}$ ($4$ and $2$ are out of order so move $2$ to the front of the list) |
| 5 | $\underline{2\,1}\,3\,4$ ($2$ and $1$ are out of order so move $1$ to the front of the list) |
| 6 | $1\,2\,3\,4$ (The list is now sorted) |
Let $F(L)$ be the number of times step 2a is executed to sort list $L$. For example, $F(\{\,4\,1\,3\,2\,\}) = 5$.
We can list all permutations $P$ of the integers $\{1, 2, \dots, n\}$ in lexicographical order, and assign to each permutation an index $I_n(P)$ from $1$ to $n!$ corresponding to its position in the list.
Let $Q(n, k) = \min(I_n(P))$ for $F(P) = k$, the index of the first permutation requiring exactly $k$ steps to sort with First Sort. If there is no permutation for which $F(P) = k$, then $Q(n, k)$ is undefined.
\columnbreak
\small Example: For $n = 4$, we have:
| $P$ | $I_4(P)$ | $F(P)$ | |
| {1, 2, 3, 4} | $1$ | $0$ | $Q(4, 0) = 1$ |
| {1, 2, 4, 3} | $2$ | $4$ | $Q(4, 4) = 2$ |
| {1, 3, 2, 4} | $3$ | $2$ | $Q(4, 2) = 3$ |
| {1, 3, 4, 2} | $4$ | $2$ | |
| {1, 4, 2, 3} | $5$ | $6$ | $Q(4, 6) = 5$ |
| {1, 4, 3, 2} | $6$ | $4$ | |
| {2, 1, 3, 4} | $7$ | $1$ | $Q(4, 1) = 7$ |
| {2, 1, 4, 3} | $8$ | $5$ | $Q(4, 5) = 8$ |
| {2, 3, 1, 4} | $9$ | $1$ | |
| {2, 3, 4, 1} | $10$ | $1$ | |
| {2, 4, 1, 3} | $11$ | $5$ | |
| {2, 4, 3, 1} | $12$ | $3$ | $Q(4, 3) = 12$ |
| {3, 1, 2, 4} | $13$ | $3$ | |
| {3, 1, 4, 2} | $14$ | $3$ | |
| {3, 2, 1, 4} | $15$ | $2$ | |
| {3, 2, 4, 1} | $16$ | $2$ | |
| {3, 4, 1, 2} | $17$ | $3$ | |
| {3, 4, 2, 1} | $18$ | $2$ | |
| {4, 1, 2, 3} | $19$ | $7$ | $Q(4, 7) = 19$ |
| {4, 1, 3, 2} | $20$ | $5$ | |
| {4, 2, 1, 3} | $21$ | $6$ | |
| {4, 2, 3, 1} | $22$ | $4$ | |
| {4, 3, 1, 2} | $23$ | $4$ | |
| {4, 3, 2, 1} | $24$ | $3$ |
Let $R(k) = \min(Q(n, k))$ over all $n$ for which $Q(n, k)$ is defined.
Find $R(12^{12})$.
Problem 524: First Sort II
Mathematical Foundation
Theorem. For all ,
Proof. From Problem 523, we established the recurrence with . Summing the telescoping series:
Lemma (Modular Inverse of 12). Let . Then .
Proof. We verify directly: . Since is prime and (as is odd and not divisible by 3), the inverse exists and is unique.
Theorem (Modular Evaluation). With and :
Proof. Since is prime and , the fraction is well-defined modulo as the product . By Fermat’s little theorem, .
Lemma (Reduction of ). Since , we have , hence .
Proof. .
Corollary. The final computation:
- ,
- ,
- ,
- .
Computing: . Dividing by : , where , so .
Editorial
E(n) = (n-1)(n+4)/12, the expected number of insertion steps to sort a random permutation using the “first sort” algorithm. Compute E(10^18) mod (10^9 + 7).
Pseudocode
MOD = 10^9 + 7
n = 10^18
a = (n - 1) mod MOD // = 48
b = (n + 4) mod MOD // = 53
inv12 = power(12, MOD - 2, MOD) // = 83333334
Return (a * b mod MOD) * inv12 mod MOD
Complexity Analysis
- Time: for the single modular exponentiation to compute . All other operations are .
- Space: .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/*
* Problem 524: First Sort II
*
* E(n) = (n-1)(n+4) / 12, the expected number of insertion steps
* to sort a random permutation via the "first sort" algorithm.
*
* Compute E(10^18) mod (10^9 + 7).
*
* Key insight: 10^18 mod p = 49 (since 10^9 ≡ -7 mod p, so 10^18 ≡ 49).
* Then (49 - 1)(49 + 4) / 12 = 48 * 53 / 12 = 2544 / 12 = 212 mod p.
* Wait, 2544 / 12 = 212 exactly, so E ≡ 212 (mod p)? Let me recheck.
*
* Actually, modular division: 2544 * inv(12) mod p.
* inv(12) = pow(12, p-2, p) = 83333334.
* 2544 * 83333334 mod (10^9 + 7).
*/
const long long MOD = 1e9 + 7;
long long power(long long base, long long exp, long long mod) {
long long result = 1;
base %= mod;
while (exp > 0) {
if (exp & 1) result = result * base % mod;
base = base * base % mod;
exp >>= 1;
}
return result;
}
int main() {
long long n = 1000000000000000000LL; // 10^18
long long p = MOD;
long long a = (n - 1) % p;
long long b = (n + 4) % p;
long long inv12 = power(12, p - 2, p);
long long ans = a % p * (b % p) % p * inv12 % p;
cout << ans << endl;
// Verification for small cases
// E(5) = (4)(9)/12 = 3
long long e5 = 4LL * 9 % p * inv12 % p;
assert(e5 == 3);
// E(4) = (3)(8)/12 = 2
long long e4 = 3LL * 8 % p * inv12 % p;
assert(e4 == 2);
return 0;
}
"""
Problem 524: First Sort II
E(n) = (n-1)(n+4)/12, the expected number of insertion steps
to sort a random permutation using the "first sort" algorithm.
Compute E(10^18) mod (10^9 + 7).
"""
from fractions import Fraction
from itertools import permutations
MOD = 10**9 + 7
# --- Method 1: Closed-form modular computation ---
def solve_closed_form(n: int, mod: int):
"""Compute E(n) = (n-1)(n+4)/12 mod p."""
a = (n - 1) % mod
b = (n + 4) % mod
inv12 = pow(12, mod - 2, mod)
return a * b % mod * inv12 % mod
# --- Method 2: Exact rational computation (verification) ---
def E_exact(n: int) -> Fraction:
"""Compute E(n) exactly as a fraction."""
return Fraction(n - 1, 1) * Fraction(n + 4, 1) / 12
# --- Method 3: Monte Carlo simulation (verification) ---
def E_simulate(n: int, trials: int = 100000) -> float:
"""Estimate E(n) by simulating the sorting algorithm."""
import random
total_steps = 0
for _ in range(trials):
perm = list(range(1, n + 1))
random.shuffle(perm)
steps = 0
while True:
# Find first descent
found = -1
for i in range(1, len(perm)):
if perm[i] < perm[i - 1]:
found = i
break
if found == -1:
break
# Remove and reinsert
val = perm.pop(found)
# Binary search for correct position in sorted prefix
lo, hi = 0, found
while lo < hi:
mid = (lo + hi) // 2
if perm[mid] < val:
lo = mid + 1
else:
hi = mid
perm.insert(lo, val)
steps += 1
total_steps += steps
return total_steps / trials
# --- Verify small cases ---
for n in range(1, 10):
exact = E_exact(n)
formula = Fraction(n - 1, 1) * Fraction(n + 4, 1) / 12
assert exact == formula, f"E({n}) mismatch"
assert E_exact(1) == 0
assert E_exact(2) == Fraction(1, 2)
assert E_exact(4) == 2
assert E_exact(5) == 3
# Verify modular computation
for n in [1, 2, 5, 10, 100, 10**6]:
exact_mod = int(E_exact(n)) % MOD if E_exact(n).denominator == 1 else \
(E_exact(n).numerator * pow(E_exact(n).denominator, MOD - 2, MOD)) % MOD
computed = solve_closed_form(n, MOD)
assert exact_mod == computed, f"Mod mismatch at n={n}"
# --- Compute the answer ---
ans = solve_closed_form(10**18, MOD)
print(ans)