These are the human proofs of Meissel-Lehmer algorithm, at full length.
The Meissel-Lehmer algorithm returns pi(x) full
This proof shows: correctness.
Write p1<p2<⋯ for the primes, Pb=p1⋯pb, and ϕ(t,b) for the number of integers 1≤n≤t with no prime factor among p1,…,pb. For m≥2, lpf(m) is its least prime factor. Two facts are used throughout. First, for real t≥0 and integers u,v≥1, ⌊⌊t/u⌋/v⌋=⌊t/(uv)⌋. Second, the inclusion-exclusion form of ϕ: ϕ(t,b)=∑d∣Pbμ(d)⌊t/d⌋, because ∑d∣gcd(n,Pb)μ(d) is 1 if gcd(n,Pb)=1 and 0 otherwise, and ⌊t/d⌋ counts the n≤t with d∣n.
If x<2, there is no prime up to x and line L1 returns 0. Assume x≥2 from now on. Line L2 sets y=⌊x1/3⌋≥1, so y3≤x<(y+1)3, and z=⌊x/y⌋. Line L3 gives the primes up to z, the table π(t) for t≤z, lpf on [2,z] and μ on [1,y]; since y≤z, a=π(y) is well defined, and pa≤y<pa+1. Since y≤x1/3≤x1/2, also ⌊x⌋≤x/y, hence ⌊x⌋≤z.
Step 1: π(x)=ϕ(x,a)+a−1−P2 with P2 as in line L10. The numbers counted by ϕ(x,a) are the 1≤n≤x all of whose prime factors are at least pa+1≥y+1>x1/3. If such an n had three prime factors counted with multiplicity, then n>(x1/3)3=x, which is impossible. So n is 1, a prime p with y<p≤x, or a product pq of primes with y<p≤q and pq≤x. The primes number π(x)−a. In a product pq with p≤q, p2≤pq≤x, so y<p≤⌊x⌋, and for such a p the possible q are the primes with p≤q≤⌊x/p⌋; as p≤⌊x/p⌋, they number π(⌊x/p⌋)−π(p−1)=π(⌊x/p⌋)−π(p)+1. Each product is counted once, for its smaller factor p. So ϕ(x,a)=1+(π(x)−a)+P2, which rearranges to the claim. All arguments of π in line L10 are at most z: ⌊x/p⌋≤⌊x/y⌋=z for p>y, and p≤⌊x⌋≤z. So line L10 computes P2 from the table.
Step 2: ϕ(x,a)=S0+S. By inclusion-exclusion, ϕ(x,a)=∑d∣Paμ(d)⌊x/d⌋. Split the sum by d≤y and d>y.
The terms with d≤y. A squarefree m≤y has all its prime factors at most y, hence at most pa, so m∣Pa; for a non-squarefree m, μ(m)=0. So these terms are ∑m≤yμ(m)⌊x/m⌋=S0, which is the value set by line L4.
The terms with d>y. Let D be the set of d∣Pa with d>y, and T the set of triples (m,b,r) with 0≤b<a, m squarefree, m≤y<mpb+1, every prime factor of m larger than pb+1, and r∣Pb. We show that (m,b,r)↦mpb+1r is a bijection from T onto D.
It maps into D: m, pb+1 and r are squarefree, with prime factors in the disjoint ranges (pb+1,pa] (as m≤y), {pb+1} and [p1,pb]; so their product is squarefree, divides Pa, and is at least mpb+1>y.
It is onto and one to one. Let d∈D have prime factors q1>q2>⋯>qk. The prefix products 1,q1,q1q2,…,d increase, the first is 1≤y and the last is d>y, so there is a unique j≥1 with q1⋯qj−1≤y<q1⋯qj. Put m=q1⋯qj−1, pb+1=qj and r=qj+1⋯qk. Then (m,b,r)∈T: b<a since qj≤pa, the prime factors of m exceed qj, and r∣Pb since its factors are below qj. Conversely, for any (m,b,r)∈T with product d, the decreasing list of the prime factors of d is that of m, then pb+1, then that of r, so the construction recovers exactly m, b and r: the prefix products through the factors of m end at m≤y, and the next one is mpb+1>y.
Therefore, using μ(mpb+1r)=μ(m)⋅(−1)⋅μ(r) for these coprime squarefree factors and the floor identity,
where the sum over m runs over the squarefree m with y/pb+1<m≤y whose prime factors exceed pb+1. For an integer m, y/pb+1<m holds if and only if ⌊y/pb+1⌋<m. The condition "every prime factor exceeds pb+1" is lpf(m)>pb+1 for m≥2; and m=1 never occurs, because pb+1≤pa≤y gives ⌊y/pb+1⌋≥1. Squarefree is μ(m)=0. So the pairs (b,m) visited by line L7 are exactly the terms of S.
Step 3: the Fenwick tree. Let Ab be the set of n∈[1,z] with no prime factor among p1,…,pb. We claim that at the start of round b of line L6, the array behind F holds 1 at the positions in Ab and 0 elsewhere. For b=0, line L5 sets all of [1,z], which is A0. If the claim holds at the start of round b, line L9 sets to 0 every multiple of pb+1 in [1,z] and changes nothing else, so afterwards the 1 positions are Ab minus the multiples of pb+1, which is Ab+1. The test F[k]=1 only skips multiples that are already 0. During round b, lines L7 and L8 run before line L9 and do not change F, so each query of round b sees Ab, and F.prefix(n)=∣Ab∩[1,n]∣=ϕ(n,b) for 0≤n≤z. The query index is n=⌊x/(mpb+1)⌋ with mpb+1≥y+1, so n≤⌊x/y⌋=z, and the query is in range. Hence line L8 adds exactly the term −μ(m)ϕ(⌊x/(mpb+1)⌋,b) of S, once for each term.
Conclusion. After the loop of line L6, the variable ϕ equals S0+S=ϕ(x,a) by Step 2. Line L10 computes P2, and line L11 returns ϕ(x,a)+a−1−P2=π(x) by Step 1. ■