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;
}

浙公网安备 33010602011771号