bzoj1041

时间:2024-07-07 08:37:56

基于圆的对称性,我们只需要考虑第一象限的整点即可
满足条件的x,y都是整数
数学上这类问题我们通常用一个量表示另一个量
y^2=(r-x)(r+x)  (r-x)(r+x)要是完全平方数
令d=gcd(r-x,r+x)
则y^2=d^2*a*b a=(r+x)/d b=(r-x)/d;
不难发现此时(a,b)=1 a≠b (不考虑坐标轴)
要想是完全平方数即a是完全平方数,b也是完全平方数
不难想到要先穷举d
通过a=(r+x)/d b=(r-x)/d;可整理得a+b=2r/d 也就是说d是2r的约数
穷举d的范围显然是1~sqrt(2r) O(sqrt(2r))
对于确定的d,我们再穷举a(1^2,2^2……) 这样我们就可以确定唯一的b(因为在第一象限)
然后在验证一下b是否是完全平方数,a,b是否互质即可

 var d,dd,r,ans,a:int64;
i,m:longint;
b:double; function gcd(a,b:int64):int64;
begin
if b= then exit(a)
else exit(gcd(b,a mod b));
end; function check(a,b:double):boolean;
var x,y:int64;
begin
if b=trunc(b) then
begin
x:=int64(trunc(a))*int64(trunc(a));
y:=int64(trunc(b))*int64(trunc(b));
if (gcd(x,y)=) and (a<>b) then exit(true);
end;
exit(false);
end; begin
readln(r);
m:=trunc(sqrt(*r));
for i:= to m do
begin
d:=int64(i);
if *r mod d= then
begin
a:=;
while (a<trunc(sqrt(r/d))) do
begin
inc(a);
b:=sqrt((*r/d)-a*a);
if check(a,b) then inc(ans);
end;
dd:=*r div d;
if dd<>d then
begin
a:=;
while (a<trunc(sqrt(r/dd))) do
begin
inc(a);
b:=sqrt(*r/dd-a*a);
if check(a,b) then inc(ans);
end;
end;
end;
end;
writeln(ans*+);
end.