题意
求一个给定的圆(x^2+y^2=R^2),在圆周上有多少个点的坐标是整数
(R<=1e+9)
题解
就是把式子处理一下然后枚举。
显然我们只需计算出正整数解的个数ans,答案即是ans*4+4。
现在考虑求ans:
x2+y2=R2
x2=R2−y2
x2=(R+y)∗(R−y)
注意到左边是平方数,右边两数的乘积也应该是平方数
记
d=gcd(R+y,R−y),A=(R+y)/d,B=(R−y)/d
则
x2=d2∗A∗B
显然因为A不能等于B,A,B分别都是平方数。
这样就能枚举了,我们先
n−−√
枚举d,再
n−−√−−−√
枚举a(a*a=A)。
这样就快多了,复杂度为
O(n−−√∗n−−√−−−√)
,大概是1e+7左右。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
LL R,ans;
bool is_q(LL x){ return ((LL)sqrt(x))*((LL)sqrt(x))==x; }
LL gcd(LL x,LL y){ return y==0?x:gcd(y,x%y); }
int main(){
freopen("bzoj1041.in","r",stdin);
freopen("bzoj1041.out","w",stdout);
scanf("%lld",&R);
for(LL i=1;i*i<=2*R;i++) if((2*R)%i==0){
LL d=i;
for(LL a=1;a*a<=2*R/d/2;a++) if(is_q(2*R/d-a*a)){
LL A=a*a, B=2*R/d-a*a;
if(gcd(A,B)==1&&A!=B) ans++;
}
if(d*d==2*R) continue;
d=2*R/d;
for(LL a=1;a*a<=2*R/d/2;a++) if(is_q(2*R/d-a*a)){
LL A=a*a, B=2*R/d-a*a;
if(gcd(A,B)==1&&A!=B) ans++;
}
}
printf("%lld\n",(ans*4+4));
return 0;
}