zoukankan      html  css  js  c++  java
  • bzoj1041

    基于圆的对称性,我们只需要考虑第一象限的整点即可
    满足条件的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是否互质即可

     1 var d,dd,r,ans,a:int64;
     2     i,m:longint;
     3     b:double;
     4 
     5 function gcd(a,b:int64):int64;
     6   begin
     7     if b=0 then exit(a)
     8     else exit(gcd(b,a mod b));
     9   end;
    10 
    11 function check(a,b:double):boolean;
    12   var x,y:int64;
    13   begin
    14     if b=trunc(b) then
    15     begin
    16       x:=int64(trunc(a))*int64(trunc(a));
    17       y:=int64(trunc(b))*int64(trunc(b));
    18       if (gcd(x,y)=1) and (a<>b) then exit(true);
    19     end;
    20     exit(false);
    21   end;
    22 
    23 begin
    24   readln(r);
    25   m:=trunc(sqrt(2*r));
    26   for i:=1 to m do
    27   begin
    28     d:=int64(i);
    29     if 2*r mod d=0 then
    30     begin
    31       a:=0;
    32       while (a<trunc(sqrt(r/d))) do
    33       begin
    34         inc(a);
    35         b:=sqrt((2*r/d)-a*a);
    36         if check(a,b) then inc(ans);
    37       end;
    38       dd:=2*r div d;
    39       if dd<>d then
    40       begin
    41         a:=0;
    42         while (a<trunc(sqrt(r/dd))) do
    43         begin
    44           inc(a);
    45           b:=sqrt(2*r/dd-a*a);
    46           if check(a,b) then inc(ans);
    47         end;
    48       end;
    49     end;
    50   end;
    51   writeln(ans*4+4); 
    52 end.
    View Code
  • 相关阅读:
    快速幂 快速乘法
    扩展欧几里得学习笔记
    求逆序数数目(树状数组+离散化)
    隐式图的遍历
    随机数生成
    推倒重来
    动态规划初步
    子集生成
    东大oj1155 等凹函数
    P1278 单词游戏
  • 原文地址:https://www.cnblogs.com/phile/p/4473130.html
Copyright © 2011-2022 走看看