Description

  求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
Input

  只有一个正整数n,n<=2000 000 000
Output

  整点个数
Sample Input
4
Sample Output
4

解题思路:还是没有解题思路啊,之前就看过这道题,但是一直不知道怎么做,今天又碰到了,开心。考虑到这个题暴力枚举是O(n)的是肯定不行的,那怎么办呢?去翻题解发看到了题解真是ORZ,看来数论那一套我这个菜鸟是真学不会了。下面附一个题解链接。这里写链接内容
x^2+y^2=r^2

化简为 y^2=(r-x)(r+x)

我们令d=gcd(r-x,r+x)

则(r-x)/d与(r+x)/d一定互质,二者相乘为完全平方数,则二者一定都为完全平方数

令r-x=d*u^2,r+x=d*v^2

则有u,v互质,u

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL R, ans;
LL gcd(LL a, LL b)
{
    return b == 0 ? a : gcd(b, a%b);
}
bool f(LL a, double b)
{
    if(b == floor(b))
    {
        LL b1 = (LL)floor(b);
        if(gcd(b1*b1, a*a) == 1 && b1*b1 != a*a) return true;
    }
    return false;
}
int main()
{
    scanf("%lld", &R);
    for(LL d = 1; d <= sqrt(2*R); d++)
    {
        if((2*R)%d == 0)
        {
            for(LL a = 1; a <= (LL)sqrt((2*R)/(2*d)); a++)
            {
                double b = sqrt(((2*R)/d) - a*a);
                if(f(a, b)) ans++;
            }
            if(d != (2*R)/d)
            {
                for(LL a = 1; a <= (LL)sqrt(d/2); a++)
                {
                    double b = sqrt(d - a*a);
                    if(f(a, b)) ans++;
                }
            }
        }
    }
    ans = ans * 4 + 4;
    printf("%lld\n", ans);
    return 0;
}