Sum of Divisors of Sum of Divisors
Let sigma(n) = sum_(d | n) d denote the sum-of-divisors function. Define S(N) = sum_(n=1)^N sigma(sigma(n)). Compute S(N) for large N.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
For an integer \(n\), we define the
Let \(C_k(N)\) be the number of integers between \(1\) and \(N\) inclusive with exactly \(k\) square prime factors. You are given some values of \(C_k(N)\) in the table below.
\[ \begin {array}{|c|c|c|c|c|c|c|} \hline & k = 0 & k = 1 & k = 2 & k = 3 & k = 4 & k = 5 \\ \hline N=10 & 7 & 3 & 0 & 0 & 0 & 0 \\ \hline N=10^2 & 61 & 36 & 3 & 0 & 0 & 0 \\ \hline N=10^3 & 608 & 343 & 48 & 1 & 0 & 0 \\ \hline N=10^4 & 6083 & 3363 & 533 & 21 & 0 & 0 \\ \hline N=10^5 & 60794 & 33562 & 5345 & 297 & 2 & 0 \\ \hline N=10^6 & 607926 & 335438 & 53358 & 3218 & 60 & 0 \\ \hline N=10^7 & 6079291 & 3353956 & 533140 & 32777 & 834 & 2 \\ \hline N=10^8 & 60792694 & 33539196 & 5329747 & 329028 & 9257 & 78 \\ \hline \end {array} \]
Find the product of all non-zero \(C_k(10^{16})\). Give the result reduced modulo \(1\,000\,000\,007\).
Problem 632: Sum of Divisors of Sum of Divisors
Mathematical Foundation
Theorem 1 (Multiplicativity of ). The function is multiplicative: whenever .
Proof. If , then every divisor of factors uniquely as with and . Therefore
Lemma 1 (Prime Power Formula). For a prime and integer ,
Proof. The divisors of are . Their sum is the geometric series .
Theorem 2 (Divisor Sieve Correctness). The additive sieve that, for each , adds to for every multiple , correctly computes for all .
Proof. For a fixed , the sieve adds to exactly when and . Since , every divisor of satisfies , so all divisors are counted. Hence is computed correctly.
Theorem 3 (Average Order). .
Proof. . More precisely, . The standard computation via and the asymptotic gives the leading term .
Lemma 2 (Sieve Range Bound). For , , where is the -th harmonic number. Thus the sieve for must extend to .
Proof. . Therefore .
Editorial
sigma(n) = sum of divisors of n. S(N) = sum_{n=1}^{N} sigma(sigma(n)). Method 1: Sieve for sigma, then lookup Method 2: Trial division (verification). We sieve sigma(n) for n = 1..M where M = max possible sigma(n). Finally, else.
Pseudocode
Sieve sigma(n) for n = 1..M where M = max possible sigma(n)
Compute S(N) = sum of sigma(sigma(n))
else
Complexity Analysis
- Time: for the sieve where , giving . The summation is with table lookups.
- Space: for the sieve array.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
* Problem 632: Sum of Divisors of Sum of Divisors
*
* sigma(n) = sum of divisors.
* Compute S(N) = sum_{n=1}^{N} sigma(sigma(n)).
*
* Method 1: Sieve for sigma, then lookup/compute
* Method 2: Trial division (verification)
*/
const int MAXN = 100001;
ll sig[MAXN];
void sieve_sigma(int N) {
memset(sig, 0, sizeof(sig));
for (int d = 1; d <= N; d++)
for (int m = d; m <= N; m += d)
sig[m] += d;
}
ll sigma_trial(ll n) {
ll total = 0;
for (ll d = 1; d * d <= n; d++) {
if (n % d == 0) {
total += d;
if (d != n / d) total += n / d;
}
}
return total;
}
int main() {
int N = 100000;
sieve_sigma(N);
// Verify
for (int n = 1; n <= 1000; n++)
assert(sig[n] == sigma_trial(n));
// Compute S(N)
ll S = 0;
for (int n = 1; n <= N; n++) {
ll sn = sig[n];
if (sn <= N) S += sig[sn];
else S += sigma_trial(sn);
}
cout << "S(" << N << ") = " << S << endl;
return 0;
}
"""
Problem 632: Sum of Divisors of Sum of Divisors
sigma(n) = sum of divisors of n.
S(N) = sum_{n=1}^{N} sigma(sigma(n)).
Method 1: Sieve for sigma, then lookup
Method 2: Trial division (verification)
"""
def sigma_sieve(N):
"""Compute sigma(n) for n=1..N via divisor sieve."""
sig = [0] * (N + 1)
for d in range(1, N + 1):
for m in range(d, N + 1, d):
sig[m] += d
return sig
def sigma_trial(n):
"""Compute sigma(n) via trial division."""
total = 0
d = 1
while d * d <= n:
if n % d == 0:
total += d
if d != n // d:
total += n // d
d += 1
return total
# Compute
N = 10000
sig = sigma_sieve(N)
# Verify sieve against trial division
for n in range(1, 1001):
assert sig[n] == sigma_trial(n), f"n={n}: sieve={sig[n]}, trial={sigma_trial(n)}"
# Compute S(N) = sum sigma(sigma(n))
def compute_S(N, sig):
total = 0
for n in range(1, N + 1):
sn = sig[n]
if sn <= N:
total += sig[sn]
else:
total += sigma_trial(sn)
return total
S_small = compute_S(10, sig)
print(f"S(10) = {S_small}") # Should be sum of sigma(sigma(n)) for n=1..10
# Verify multiplicativity
assert sig[1] == 1
assert sig[2] == 3
assert sig[6] == 12
assert sig[12] == 28
assert sig[28] == 56
print(f"S(100) = {compute_S(100, sig)}")
print(f"S(1000) = {compute_S(1000, sig)}")
print("All verifications passed.")