P2508 [HAOI2008] 圆上的整点

Sol

我们只考虑第一象限的满足条件的个数,最终再 \(\times 4\) 即可。

我们有 \(x^2+y^2=r^2\),则有 \(x^2=r^2-y^2\)

进一步的 \(x^2=(r+y)(r-y)\)

我们取 \(r+y\)\(r-y\) 的最大公约数 \(d=\gcd(r+y,r-y)\),我们将他们分别表示为 \(ad\)\(bd\),则 \(x^2=d^2ab\),且有 \(\gcd(a,b)=1\),也就是说 \(a\)\(b\) 没有公约数。

因为 \(a\)\(b\) 没有公约数又要满足 \(x^2=(dst)^2\),所以 \(s,t\) 不能由 \(a\)\(b\) 中的两个质数合在一起而成,所以 \(a,b\) 都为平方数,即 \(a=s^2\)\(b=t^2\)

两边开平方 \(x=dst\)

因为有 \(r+y=s^2d\)\(r-y=t^2d\)

两式相加得:\(2r=(s^2+t^2)d\),所以我们可以枚举 \(d|2r\),接下来再枚举 \(s\),再算出 \(t,a,b\)

两式相减得:\(y=\frac{1}{2}(s^2-t^2)d\),结合 \(x=dst\) 算出 \(x,y\),满足条件即可将答案加 \(2\),即 \(x^2+y^2=r^2\)\(y^2+x^2=r^2\) 均可。

再加上坐标轴上的一个点,最后拓展到四个象限即可。

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long 

int r,ans;

void solve(int d)
{
    for(int s=1;s*s<=r/d;s++)
    {
        int a=s*s;
        int b=r/d-a;
        int t=sqrt(b);
        if(__gcd(s,t)==1&&a+b==r/d)
        {
            int X=d*s*t;
            int Y=(a-b)/2*d;
            if(X>0&&Y>0&&X*X+Y*Y==(r/2)*(r/2))
                ans+=2;
        }
    }
    return ;
}

signed main()
{
    cin>>r;
    r*=2;
    for(int d=1;d*d<=r;d++)
        if(r%d==0)
        {
            solve(d);
            if(d*d!=r)
                solve(r/d);
        }
    cout<<(ans+1)*4;
    return 0;
}
posted @ 2025-02-11 17:32  tmp_get_zip_diff  阅读(36)  评论(1)    收藏  举报