给定圆 (x^2+y^2=r^2),求圆周上有多少个点的坐标是整数。 (rleq 2 imes 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;
}