Project Euler Problem 643
Two positive integers a and b are 2-friendly when gcd(a,b) = 2^t, t gt 0.
Solution
Answer: 968274154
Let
$$f(n)=#{(p,q):1\le p<q\le n,\ \gcd(p,q)=2^t,\ t>0}.$$
We need $f(10^{11}) \bmod 1,000,000,007$.
1. Mathematical analysis
If $\gcd(p,q)=2^t$ with $t>0$, write
$$p=2^t a,\qquad q=2^t b,$$
where $\gcd(a,b)=1$.
Since $p<q\le n$,
$$1\le a<b\le \left\lfloor \frac{n}{2^t}\right\rfloor.$$
Thus for each $t\ge 1$, the number of valid pairs equals the number of coprime pairs $(a,b)$ with $a<b\le m$, where
$$m=\left\lfloor \frac{n}{2^t}\right\rfloor.$$
Counting coprime pairs
For fixed $b$, the number of $a<b$ with $\gcd(a,b)=1$ is Euler’s totient:
$$\varphi(b).$$
Hence
$$C(m)=\sum_{b=2}^{m}\varphi(b).$$
Define the totient summatory function
$$\Phi(m)=\sum_{k=1}^{m}\varphi(k).$$
Then
$$C(m)=\Phi(m)-1.$$
Therefore,
$$f(n) = \sum_{t\ge 1} \left( \Phi!\left(\left\lfloor \frac{n}{2^t}\right\rfloor\right)-1 \right).$$
Since $2^t>n$ eventually, only $O(\log n)$ terms exist.
Fast computation of $\Phi(n)$
Use the classical identity
$$\sum_{d\le n}\varphi(d)\left\lfloor \frac{n}{d}\right\rfloor = \frac{n(n+1)}{2}.$$
Rearranging:
$$\Phi(n) = \frac{n(n+1)}{2} - \sum_{d=2}^{n} \Phi!\left(\left\lfloor \frac{n}{d}\right\rfloor\right).$$
The key optimization is grouping equal values of $\lfloor n/d\rfloor$:
if
$$v=\left\lfloor \frac{n}{d}\right\rfloor,$$
then all $d\in[l,r]$ share the same $v$, where
$$r=\left\lfloor \frac{n}{v}\right\rfloor.$$
This reduces complexity to roughly $O(n^{2/3})$-style memoized divide-and-conquer, fast enough for $10^{11}$.
2. Python implementation
MOD = 1_000_000_007
LIMIT = 5_000_000
# Sieve Euler phi up to LIMIT
phi = list(range(LIMIT + 1))
for i in range(2, LIMIT + 1):
if phi[i] == i: # i is prime
for j in range(i, LIMIT + 1, i):
phi[j] -= phi[j] // i
# Prefix sums of phi
phi_prefix = [0] * (LIMIT + 1)
running = 0
for i in range(LIMIT + 1):
running += phi[i]
phi_prefix[i] = running
# Memoized summatory totient
memo = {0: 0}
def Phi(n):
"""Return sum_{k<=n} phi(k)."""
if n <= LIMIT:
return phi_prefix[n]
if n in memo:
return memo[n]
result = n * (n + 1) // 2
l = 2
while l <= n:
v = n // l
r = n // v
result -= (r - l + 1) * Phi(v)
l = r + 1
memo[n] = result
return result
def f(n):
total = 0
t = 1
while True:
m = n >> t # floor(n / 2^t)
if m == 0:
break
total += Phi(m) - 1
total %= MOD
t += 1
return total
print(f(10**11))
3. Code walkthrough
Step 1: Totient sieve
We compute all $\varphi(k)$ up to a cutoff (LIMIT = 5_000_000) using the standard Euler sieve.
Step 2: Prefix sums
We build
$$\Phi(n)=\sum_{k\le n}\varphi(k)$$
for all small $n$.
Step 3: Recursive summatory totient
For large $n$, we use
$$\Phi(n) = \frac{n(n+1)}{2} - \sum_{d=2}^{n} \Phi!\left(\left\lfloor \frac{n}{d}\right\rfloor\right),$$
grouping identical quotients to make it efficient.
Step 4: Compute $f(n)$
We sum
$$\Phi!\left(\left\lfloor n/2^t\right\rfloor\right)-1$$
for $t=1,2,\dots$.
Verification on given examples
For $n=100$:
$$f(100)=1031,$$
matching the statement.
For $n=10^6$:
$$f(10^6)\equiv 321418433 \pmod{1,000,000,007},$$
also matching the statement.
So the derivation and implementation are consistent.
The computation for $n=10^{11}$ gives:
Answer: 968274154