3
$\begingroup$

I am trying to solve a problem on codeforces, to be precised, this problem. I was able to figure out that the solution is $N(n) - N(n-1)$ where $N(n)$ is the number of lattice points withing a circle centered at the origin. I wrote a solution using the formula from MathWorld.WolframAlpha

$$N(r) = 1 + 4\lfloor r\rfloor + \sum^{\lfloor r\rfloor}_{i = 1} \lfloor \sqrt{r^2 - i^2}\rfloor$$

Since $r$ is an integer in this case, I didn't bother much about the precision.

Here is the code I wrote.

long long N(int r){
    long long s = 0;
    for(int i = 1; i<=r; i++) s+=(int)sqrt(r*r-i*i);
    s*=4;
    s+=1+4*r;
    return s;
}

This function worked well for small integers but failed for larger ones. I can't figure out why.

I inspected accepted submissions from other coders and I found out some of them used a simplified version of $N(n) - N(n-1)$, more precisely

$$N(n) - N(n-1) = 4\lfloor n\sqrt 2\rfloor$$

which I tried to derive and couldn't.

I am more interested in knowing how to simplify to get the expression but if anyone understands why the code fails, I'd really appreciate that as well. Thanks.

$\endgroup$
4
  • $\begingroup$ In your expression $N(n) - N(n-1) = 4n \sqrt{2}$, is it the floor or the ceiling or rounded to the nearest integer? $\endgroup$ Commented Sep 17, 2014 at 21:10
  • $\begingroup$ @user2566092 it is the floor $\endgroup$
    – Olayinka
    Commented Sep 17, 2014 at 21:19
  • $\begingroup$ The supposed formula $N(n)-N(n-1) = 4[n\sqrt2]$ is really, really false. For one thing, the asymptotic size of the difference is $\pi n^2 - \pi(n-1)^2 \sim 2\pi n$, not $4\sqrt2 n$. Surely your computations revealed that? $\endgroup$ Commented Sep 18, 2014 at 16:08
  • $\begingroup$ Is there a $4$ before the summation in WA formula? $\endgroup$
    – Bob Dobbs
    Commented Jun 23 at 16:11

1 Answer 1

1
$\begingroup$

If your integers are stored as $B$ bits long, then you need r to be only $B/2$ bits or less, i.e. $r \leq 2^{B/2 - 1}$. (The minus one is because you are using signed integers.) Otherwise you will get integer overflow when you compute $r * r$ and the answer won't be correct. Using doubles (long floats) instead of integers won't really help either, because you won't have enough precision to get $r*r - i*i$ when $r$ and $i$ are both large, e.g. when you try to set $i = r-1$ and $r$ is large you will actually get $i*i = r*r$ so the expression will evaluate to zero.

The other possibilities are that when you convert r*r - i*i to a floating point to compute the square root, the squared value might not fit precisely into the bits of mantissa precision. So actually you might need $r$ to be a few orders of magnitude less than $2^{B/2}$. Also, when you convert to a floating point, it's possible that when you compute the square root you will get a floating point answer slightly smaller than the true integer answer when the expression under the square root is a perfect integer square. Then when you cast to integer, your answer will be 1 less than it should be. To test for this and fix it, if the integer under the square-root is $A$ and you compute the floored square-root to be $B$, then you should have $A - B^2 \leq 2B$, or equivalently $(B+1)^2 > A$ (all integer arihmetic). If not, then add one to $B$.

$\endgroup$
5
  • $\begingroup$ but the limit of r is $4\cdot 10^7$ which when squared can still fit into a signed long long $\endgroup$
    – Olayinka
    Commented Sep 17, 2014 at 21:24
  • $\begingroup$ @Olayinka I'm not sure what's going on then. If the formula is correct, your function should work for all integers $\leq 10^9$ if long longs are 64 bit, so the only thing I can think is that you are running on an older machine where long longs are still 32 bit. $\endgroup$ Commented Sep 17, 2014 at 22:29
  • $\begingroup$ @Olayinka Actually I did think of something. When your expression under the square root is a perfect square, it's possible because of round-off error that you will get a floating point number slightly less than the integer square root, so when you cast to an integer you will get 1 less than you should. Check to see if your incorrect answers are close but slightly smaller than the correct answer, and if so, that's likely what's going on. I'll update my answer to reflect this. $\endgroup$ Commented Sep 17, 2014 at 22:31
  • $\begingroup$ i understand, how do you suggest I fix this? $\endgroup$
    – Olayinka
    Commented Sep 18, 2014 at 9:00
  • $\begingroup$ @Olayinka See the bottom of my updated answer for a possible fix. $\endgroup$ Commented Sep 18, 2014 at 15:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .