给定圆 \(x^2+y^2=r^2\),求圆周上有多少个点的坐标是整数。 \(r\leq 2\times 10^9\)
Solution
将原式化为 \(y^2=r^2-x^2=(r-x)(r+x)\),设 \(u,v\ s.t.\ r-x=du, r+x=dv, (u,v)=1\),则 \(y^2=d^2uv\),于是 \(uv\) 必然是完全平方数,故可设 \(u=s^2,v=t^2\),则有 \(y^2=d^2s^2t^2\)
只考虑第一象限内的部分,设答案为 \(ans\),那么原问题答案就是 \(4(ans+1)\)
考虑如何计算 \(ans\),由 \(r-x=du,r+x=dv\) 解得 \(x=\frac{t^2-s^2}{2}d,\ 2r=(t^2+s^2)d\),于是我们可以暴力枚举 \(2r\) 的约数 \(d\),枚举每一个 \(s\),算出其对应的 \(t\),然后计算出 \(x,y\) 看其是否合法来统计贡献
#include <bits/stdc++.h>
using namespace std;
#define int long long
int r;
signed main() {
int ans=0;
cin>>r;
for(int i=1;i*i<=2*r;i++) if(2*r%i==0) {
int d=i;
for(int s=1;s*s<=2*r/d;s++) {
int t=sqrt(2*r/d-s*s);
if(__gcd(s,t)!=1) continue;
if((t*t+s*s)==2*r/d) {
int x=(s*s-t*t)/2*d;
int y=d*s*t;
if(x>0&&y>0&&x*x+y*y==r*r) ans+=2;
}
}
if(i*i==2*r) continue;
d=2*r/i;
for(int s=1;s*s<=2*r/d;s++) {
int t=sqrt(2*r/d-s*s);
if(__gcd(s,t)!=1) continue;
if((t*t+s*s)==2*r/d) {
int x=(s*s-t*t)/2*d;
int y=d*s*t;
if(x>0&&y>0&&x*x+y*y==r*r) ans+=2;
}
}
}
cout<<4*(ans+1)<<endl;
}