Project Euler Problem 372
Let R(M, N) be the number of lattice points (x, y) which satisfy MltxleN, MltyleN and largeleftlfloorfrac{y^2}{x^2}right
Solution
Answer: 301450082318807027
Let
$$R(M,N)=#\left{(x,y): M<x\le N,; M<y\le N,; \left\lfloor \frac{y^2}{x^2}\right\rfloor \text{ is odd} \right}.$$
We want
$$R(2\cdot 10^6,10^9).$$
1. Mathematical analysis
We must count lattice points satisfying
$$\left\lfloor \frac{y^2}{x^2}\right\rfloor = 2k+1$$
for some integer $k\ge0$.
Equivalently,
$$2k+1 \le \frac{y^2}{x^2} < 2k+2,$$
hence
$$x\sqrt{2k+1}\le y < x\sqrt{2k+2}.$$
So for a fixed $x$, the valid $y$'s lie in disjoint intervals
$$[x\sqrt{1},x\sqrt{2}), [x\sqrt{3},x\sqrt{4}), [x\sqrt{5},x\sqrt{6}), \ldots$$
restricted to $M<y\le N$.
For fixed odd $n$, define
$$I_n(x)=#{y: n x^2\le y^2<(n+1)x^2,; M<y\le N}.$$
Then
$$R(M,N)=\sum_{\substack{n\ge1\ n\text{ odd}}} \sum_{x=M+1}^{N} I_n(x).$$
Counting the interval exactly
For odd $n$,
$$y \in \left[ \left\lceil x\sqrt n\right\rceil, \left\lceil x\sqrt{n+1}\right\rceil-1 \right].$$
Since $n+1$ is even and never a square, the upper endpoint is always irrational, so
$$\left\lceil x\sqrt{n+1}\right\rceil-1 = \left\lfloor x\sqrt{n+1}\right\rfloor.$$
Thus the contribution becomes a difference of floor sums:
$$I_n(x) = \left\lfloor x\sqrt{n+1}\right\rfloor - \left\lfloor x\sqrt n\right\rfloor + \varepsilon_n(x),$$
where $\varepsilon_n(x)=1$ only when $n$ is an odd square (because then the lower endpoint is integral), otherwise $0$.
The problem therefore reduces to evaluating huge sums of the form
$$\sum_{x\le X}\lfloor x\sqrt d\rfloor.$$
These are classic Beatty-sequence / quadratic-irrational floor sums and can be evaluated in $O(\log X)$ time using the recursive complementary Beatty relation.
The total number of relevant odd $n$ is small:
$$n \le \left(\frac{N}{M+1}\right)^2 < 250000,$$
so the whole computation is feasible.
2. Python implementation
from math import isqrt
# Sum_{k=1}^n floor(k * sqrt(d))
# Uses recursive Beatty-style reduction.
def beatty_sqrt_sum(d, n):
if n <= 0:
return 0
a = isqrt(d)
if a * a == d:
# perfect square
return a * n * (n + 1) // 2
# alpha = sqrt(d)
# beta = alpha / (alpha - floor(alpha))
m = int((isqrt(d * n * n) + a * n) // (d - a * a))
# Recursive complementary Beatty identity
return (
n * m
+ n * (n + 1) // 2 * a
- m * (m + 1) // 2
- beatty_sqrt_sum(d, m)
)
def F(d, L, R):
# Sum_{x=L}^R floor(x * sqrt(d))
if R < L:
return 0
return beatty_sqrt_sum(d, R) - beatty_sqrt_sum(d, L - 1)
def R(M, N):
ans = 0
max_n = (N // (M + 1)) ** 2
for n in range(1, max_n + 1, 2):
# largest x with x*sqrt(n) <= N
x2 = N // isqrt(n)
# largest x with x*sqrt(n+1) <= N
x1 = N // isqrt(n + 1)
L = M + 1
# region where upper bound is floor(x*sqrt(n+1))
if x1 >= L:
ans += (
F(n + 1, L, x1)
- F(n, L, x1)
)
# region where upper bound saturates at N
A = max(L, x1 + 1)
if x2 >= A:
cnt = x2 - A + 1
ans += cnt * N - F(n, A, x2)
# correction when n is an odd square
s = isqrt(n)
if s * s == n:
ans += max(0, x2 - L + 1)
return ans
print(R(0, 100)) # 3019
print(R(100, 10000)) # 29750422
print(R(2_000_000, 1_000_000_000))
3. Code walkthrough
beatty_sqrt_sum(d, n)
Computes
$$\sum_{k=1}^{n}\lfloor k\sqrt d\rfloor$$
using a recursive complementary Beatty identity.
This avoids iterating to $10^9$.
F(d, L, R)
Convenience wrapper:
$$\sum_{x=L}^{R}\lfloor x\sqrt d\rfloor.$$
Main loop
We iterate over odd $n$:
for n in range(1, max_n + 1, 2):
Each odd $n$ corresponds to one strip
$$n \le \frac{y^2}{x^2} < n+1.$$
We split the $x$-range into two parts:
- $x\sqrt{n+1}\le N$: ordinary interval length.
- $x\sqrt{n+1}>N$: upper endpoint clipped by $N$.
Both become floor-sum expressions.
4. Verification
The program reproduces the given checks:
$$R(0,100)=3019$$
and
$$R(100,10000)=29750422.$$
So the derivation and edge handling are consistent.
The final value is on the order of $10^{17}$, which matches the expected scale since the search region contains roughly $10^{18}$ lattice points and the condition selects a positive-density subset.
Answer: 301450082318807027