Prime Counting Function
Let pi(x) denote the number of primes not exceeding x. Compute sum_(k=1)^(10^4) pi(k^2).
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A positive integer is called extitheptaphobic if it is not divisible by seven and no number divisible by seven can be produced by swapping two of its digits. Note that leading zeros are not allowed before or after the swap.
For example, \(17\) and \(1305\) are heptaphobic, but \(14\) and \(132\) are not because \(14\) and \(231\) are divisible by seven.
Let \(C(N)\) count heptaphobic numbers smaller than \(N\). You are given \(C(100) = 74\) and \(C(10^4) = 3737\).
Find \(C(10^{13})\).
Problem 954: Prime Counting Function
Mathematical Analysis
The Prime Counting Function
The prime counting function gives the number of primes . By the Prime Number Theorem (proved independently by Hadamard and de la Vallee Poussin in 1896):
A better approximation is the logarithmic integral: .
Estimating the Sum
We need for , so the largest argument is . By PNT:
The sum is approximately:
For : , which is in the right ballpark.
Prefix Sum Approach
Theorem (Prefix Sum Method). If is the prefix sum of the prime indicator, then for all , and the desired sum is .
This allows us to compute all required values with a single sieve followed by lookups.
Concrete Examples
| 1 | 1 | 0 |
| 2 | 4 | 2 |
| 3 | 9 | 4 |
| 4 | 16 | 6 |
| 5 | 25 | 9 |
| 10 | 100 | 25 |
| 100 | 10000 | 1229 |
| 1000 | 78498 |
Partial sums: . Wait, let me be precise: .
Derivation
Editorial
Compute sum_{k=1}^{10^4} pi(k^2) where pi(x) is the prime counting function. Algorithm: 1. Sieve of Eratosthenes up to (10^4)^2 = 10^8 2. Build prefix sum of prime indicator 3. Sum pi(k^2) for k = 1, …, 10^4 Complexity: O(M log log M) time, O(M) space, M = 10^8. We sieve of Eratosthenes** up to . Finally, build prefix sum** array: for .
Pseudocode
Sieve of Eratosthenes** up to $M = (10^4)^2 = 10^8$
Build prefix sum** array: $P[n] = P[n-1] + [n \text{ is prime}]$ for $n = 2, \ldots, M$
Accumulate** $S = \sum_{k=1}^{10^4} P[k^2]$
Memory Optimization
A boolean sieve for entries requires 100 MB. Using a bitset reduces this to ~12.5 MB. Alternatively, a segmented sieve can be used with memory, though the prefix-sum approach requires storing cumulative counts.
Verification
Cross-check with known values: (well-established). The sum of the first few terms can be verified manually.
Proof of Correctness
Theorem. The Sieve of Eratosthenes correctly identifies all primes up to .
Proof. If is composite, then with , so . The sieve marks as composite when processing the smallest prime factor of , which is . Hence every composite number is correctly identified.
Corollary. The prefix sum equals for all .
Complexity Analysis
- Sieve: time, space (or with bitset).
- Prefix sum: time.
- Final summation: time.
- Total: with .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
/*
* Problem 954: Prime Counting Function
*
* Compute sum_{k=1}^{10^4} pi(k^2).
*
* Algorithm:
* 1. Sieve primes up to (10^4)^2 = 10^8
* 2. Build prefix sum array of prime indicator
* 3. Sum pi(k^2) for k = 1 to 10^4
*
* Complexity: O(M log log M), M = 10^8.
* Memory: ~100 MB for boolean sieve + prefix sums.
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
const int N = 10000;
const int M = N * N; // 10^8
// Sieve of Eratosthenes
vector<bool> is_prime(M + 1, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; (long long)i * i <= M; i++) {
if (is_prime[i]) {
for (int j = i * i; j <= M; j += i) {
is_prime[j] = false;
}
}
}
// Build prefix sum: pi[n] = number of primes <= n
vector<int> pi(M + 1, 0);
for (int n = 1; n <= M; n++) {
pi[n] = pi[n - 1] + (is_prime[n] ? 1 : 0);
}
// Sum pi(k^2) for k = 1 to N
long long total = 0;
for (int k = 1; k <= N; k++) {
total += pi[(long long)k * k];
}
cout << total << endl;
return 0;
}
"""
Problem 954: Prime Counting Function
Compute sum_{k=1}^{10^4} pi(k^2) where pi(x) is the prime counting function.
Algorithm:
1. Sieve of Eratosthenes up to (10^4)^2 = 10^8
2. Build prefix sum of prime indicator
3. Sum pi(k^2) for k = 1, ..., 10^4
Complexity: O(M log log M) time, O(M) space, M = 10^8.
"""
from math import isqrt, log
def sieve_prefix(M: int) -> list[int]:
"""Compute prefix sum of prime indicator up to M.
Returns array P where P[n] = number of primes <= n.
"""
is_prime = bytearray(b'\x01') * (M + 1)
is_prime[0] = is_prime[1] = 0
for i in range(2, isqrt(M) + 1):
if is_prime[i]:
is_prime[i * i::i] = bytearray(len(is_prime[i * i::i]))
# Build prefix sum in-place
P = [0] * (M + 1)
for n in range(1, M + 1):
P[n] = P[n - 1] + is_prime[n]
return P
def solve(N: int = 10**4) -> int:
"""Compute sum of pi(k^2) for k = 1 to N."""
M = N * N
P = sieve_prefix(M)
return sum(P[k * k] for k in range(1, N + 1))
# --- Compute answer ---
N = 10**4
M = N * N
P = sieve_prefix(M)
answer = sum(P[k * k] for k in range(1, N + 1))
# Verify known values
assert P[100] == 25, f"pi(100) = {P[100]}"
assert P[1000000] == 78498, f"pi(10^6) = {P[1000000]}"
print(answer)