Official

D - Squares in Circle Editorial by en_translator


Define the coordinates so that the centers of the squares lie on the lattice points, and let \((0,0)\) be the center of the circle.

Among the conforming pairs \((i,j)\), we can easily count those with \(i=0\) or \(j=0\); there are \(4(R-1)+1\) of them, where one is on the origin and the others are in one of the four directions.

Next, let us count those with \(i\neq 0\) and \(j\neq 0\). By symmetry, it is sufficient to count those with \(i>0\) and \(j>0\), and multiply the count by four.

We enumerate \(i\) for \(1,2,\ldots,R-1\) in order. Then, the maximum integer \(j\) with \((i+0.5)^2+(j+0.5)^2\leq R^2\) decreases monotonically.

Thus, by managing the maximum \(j\) in the manner of the sliding window trick, we obtain a solution with time complexity \(\mathrm{O}(R)\). For more details on this trick, please refer to the sample code too.

Note that while we may using decimals for this problem, in general it is vulnerable to precision errors, so it is a good idea to stick to integers whenever possible.

For example, we use \((i+0.5)^2+(j+0.5)^2\leq R^2\) in this problem, where we may multiply the both hand sides by \(4\) to make it \((2i+1)^2+(2j+1)^2\leq 4R^2\), which we can evaluate only with integers.

Sample code (C++):

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ll r;
    cin >> r;
    auto in = [&](ll a, ll b) {
        return (2 * a + 1) * (2 * a + 1) + (2 * b + 1) * (2 * b + 1) <= 4 * r * r;
    };
    ll cnt = 0;
    ll up = r - 1;
    ll res = (r - 1) * 4 + 1;
    for(ll x = 1; in(x, 1); x++) {
        while(!in(x, up)) --up;
        cnt += up;
    }
    res += cnt * 4;
    cout << res << endl;
}

posted:
last update: