Mobius Function Partial Sums
The Mertens function is defined as M(n) = sum_(k=1)^n mu(k), where mu is the Mobius function. Compute sum_(n=1)^(10^5) |M(n)|.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A very odd number is a number which contains only odd digits and is divisible by
Define
Find
Problem 974: Mobius Function Partial Sums
Mathematical Foundation
Definition 1 (Mobius Function). For :
Theorem 1 (Mobius Inversion Formula). If for all , then .
Proof. We verify:
Setting , the inner sum becomes , using the fundamental identity . Hence the double sum equals .
Theorem 2 (Fundamental Identity of ). For all , .
Proof. For , the sum is . For , write . Then , since only squarefree divisors contribute.
Theorem 3 (Mertens Function and the Riemann Hypothesis). The Riemann Hypothesis is equivalent to the assertion that for every .
Proof. (Sketch.) The Dirichlet series converges for . By Perron’s formula, . The poles of correspond to zeros of . If all nontrivial zeros satisfy , the residue contributions give . Conversely, if for all , then converges for , implying there.
Lemma 1 (Computing via Sieve). The Mobius function can be computed for all in time using a modified Sieve of Eratosthenes that tracks the smallest prime factor and squarefree status.
Proof. Initialize . For each prime found by the sieve, for each multiple : if , set ; otherwise, multiply by . This correctly computes since is multiplicative and if , if . The sieve visits each multiple of each prime, totaling .
Editorial
Compute the sum of |M(n)| for n = 1 to 10^5, where M(n) = sum_{k=1}^{n} mu(k) is the Mertens function. We compute mu via sieve. Finally, compute prefix sums and accumulate |M(n)|.
Pseudocode
Compute mu via sieve
Compute prefix sums and accumulate |M(n)|
Complexity Analysis
- Time: for the Mobius sieve, plus for the accumulation loop. Total: .
- Space: for the arrays and
is_composite.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int N = 100000;
vector<int> mu(N+1,0); mu[1]=1;
vector<bool> is_p(N+1,true); vector<int> primes;
for(int i=2;i<=N;i++){
if(is_p[i]){primes.push_back(i);mu[i]=-1;}
for(int p:primes){
if((long long)i*p>N)break;
is_p[i*p]=false;
if(i%p==0){mu[i*p]=0;break;}
else mu[i*p]=-mu[i];
}
}
long long M=0, ans=0;
for(int n=1;n<=N;n++){M+=mu[n]; ans+=abs(M);}
cout<<ans<<endl;
return 0;
}
"""
Problem 974: Mobius Function Partial Sums
Compute the sum of |M(n)| for n = 1 to 10^5, where M(n) = sum_{k=1}^{n} mu(k)
is the Mertens function.
Key results:
- mu(n) is the Mobius function: mu(1)=1, mu(n)=0 if n has squared factor,
mu(n)=(-1)^k if n is product of k distinct primes
- M(n) = sum of mu(1..n) is the Mertens function
- The Mertens conjecture |M(n)| < sqrt(n) was disproved but holds for small n
- answer = sum of |M(n)| for n = 1..10^5
Methods:
1. linear_sieve_mobius — compute mu(n) via linear sieve
2. mertens_function — prefix sums to get M(n)
3. mobius_distribution — count of mu(n) = -1, 0, +1
4. mertens_vs_sqrt_bound — compare |M(n)| against sqrt(n)
"""
from collections import Counter
def linear_sieve_mobius(N):
"""Compute mu[0..N] using a linear sieve. Returns (mu, primes)."""
mu = [0] * (N + 1)
mu[1] = 1
is_prime = [True] * (N + 1)
primes = []
for i in range(2, N + 1):
if is_prime[i]:
primes.append(i)
mu[i] = -1
for p in primes:
if i * p > N:
break
is_prime[i * p] = False
if i % p == 0:
mu[i * p] = 0
break
else:
mu[i * p] = -mu[i]
return mu, primes
def mertens_function(mu, N):
"""Compute M[0..N] where M[n] = sum mu[1..n]."""
M = [0] * (N + 1)
for n in range(1, N + 1):
M[n] = M[n - 1] + mu[n]
return M
def mobius_distribution(mu, N):
"""Count occurrences of mu(n) = -1, 0, +1 for n = 1..N."""
counts = Counter(mu[n] for n in range(1, N + 1))
return counts
def mertens_vs_sqrt(M, N, step=10):
"""Compute |M(n)| / sqrt(n) at sampled points."""
ns = list(range(step, N + 1, step))
ratios = [abs(M[n]) / (n ** 0.5) for n in ns]
return ns, ratios
# Verification
# Known: mu(1)=1, mu(2)=-1, mu(3)=-1, mu(4)=0, mu(5)=-1, mu(6)=1
# M(1)=1, M(2)=0, M(3)=-1, M(4)=-1, M(5)=-2, M(6)=-1
_mu, _ = linear_sieve_mobius(10)
assert _mu[1] == 1
assert _mu[2] == -1
assert _mu[3] == -1
assert _mu[4] == 0
assert _mu[5] == -1
assert _mu[6] == 1
_M = mertens_function(_mu, 10)
assert _M[1] == 1
assert _M[6] == -1
# Main computation
N = 10 ** 5
mu, primes = linear_sieve_mobius(N)
M = mertens_function(mu, N)
answer = sum(abs(M[n]) for n in range(1, N + 1))
print(answer)
# Visualization — 4-panel figure