zoukankan      html  css  js  c++  java
  • 20201016day37 刷题记录

    1 [HAOI2008]圆上的整点

    problem

    给定(R),求圆周(x^2+y^2=R^2)上整点的个数。整点的定义是点((a,b),a,binmathbb Z)

    solution

    [Y^2=(R+X)(R-X) ]

    [egin{equation} Y=sqrt{(R+X)(R-X)} end{equation} ]

    (d=gcd (R+X,R-X)),则设

    [egin{equation} A=dfrac{R-X}{d},B=dfrac{R+X}{d}end{equation} ]

    (ecause d)(R+X,R-X)的最大公约数,( herefore)必定存在(gcd(A,B)=1),即(A⊥ B)
    ((2))代入((1))

    [Y^2=d^2 imes A imes B ]

    由于(d^2,Y^2)一定为完全平方数,则(A imes B)必定为一个完全平方数
    又因为(A⊥B,A eq B),则(A,B)本身都为一完全平方数
    ( herefore)(A)的算术平方根为(a)(B)的算术平方根为(b),即(A=a^2,B=b^2)
    由于(A eq B, herefore a eq b),令(a<b),代入((2)),得

    [egin{equation} a^2=dfrac{R-X}{d}end{equation} ]

    [egin{equation} b^2=dfrac{R+X}{d}end{equation} ]

    ((3)+(4))得:

    [egin{equation}a^2+b^2=dfrac{2R}{d}end{equation} ]

    ((5))观察可知:(2R=Td,Tin mathbb N_+),即(d)(2R)的一约数
    而约数的个数确定,是基于分解质因数<对(Z)分解质因数个数最多为(sqrt{Z})>,则(1le dle sqrt{2R})
    有了上面的推理,实现的方法为:
    枚举(din left[1,sqrt{2R} ight]),然后根据上述推理可知:必先判断(d)是否是(2R)的一个约数

    此时(d)(2R)的约数有两种情况:(d=dfrac{2R}{d})(d=d)。(如(d=d)就是(dle sqrt{2R})&&(dfrac{2R}{d}ge sqrt{2R})的情况 )

    第一种情况:(d=dfrac{2R}{d})。枚举(a∈left[1,sqrt{dfrac{2R}{2d}} ight]) <由(2 imes a^2 < 2 imesdfrac{R}{d})转变来>,算出对应的(b=sqrt{dfrac{2R}{d}}),检查是否此时的(A,B)满足:(A≠B)(A,B)互质 <根据上面的推理可知必需满足此条件>,若是就将答案加1

    第二种情况:(d=d)。枚举(a∈left[ 1,sqrt{dfrac{d}{2}} ight])<由(2 imes a^2< d)转变来>,算出对应的(b=sqrt{d-a^2}),检查是否此时的(A,B)满足:(A≠B)(A,B)互质 <根据上面的推理可知必需满足此条件>,若是就将答案加1

    因为这样只算出了第一象限的情况<上面枚举时均是从1开始枚举>,根据圆的对称性,其他象限的整点数与第一象限中的整点数相同,最后,在象限轴上的4个整点未算,加上即可,那么最后答案为(ans=4 imes ext{第一象限整点数}+4)

    【时间复杂度分析】枚举(d)(O(sqrt(2R))),然后两次枚举a:O(sqrt(d/2))+O(sqrt(R/d)),求最大公约数:O(logN)

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL R,ans=0;
    LL gcd(LL x,LL y){
        if(x%y==0) return y;
        else return gcd(y,x%y);
    }
    bool check(LL y,double x)
    {
          if(x==floor(x))//判断整点
          {
                LL x1=(LL)floor(x);
                if(gcd(x1*x1,y*y)==1 && x1*x1!=y*y)//gcd(A,B)=1并且A!=B
                      return true;
          }
          return false;
    }
    int main()
    {
          scanf("%lld",&R);
          for(LL d=1;d<=(LL)sqrt(2*R);d++)
          {
                if((2*R)%d==0)
                {
                      for(LL a=1;a<=(LL)sqrt(2*R/(2*d));a++)//2*a^2<2*r/d
                      {
                            double b=sqrt(((2*R)/d)-a*a);
                            if(check(a,b))
                                  ans++;
                      }
                      if(d!=(2*R)/d)
                      {
                            for(LL a=1;a<=(LL)sqrt(d/2);a++)//2*a^2<d
                            {
                                  double b=sqrt(d-a*a);
                                  if(check(a,b))
                                        ans++;
                            }
                      }
                }
          }
          printf("%lld
    ",ans*4+4);
          return 0;
    }
    

    圆内整点

  • 相关阅读:
    actionBar-进入界面闪烁问题解决
    softInputMode- 软件盘的设置
    LinearLayout -设置负值属性
    launcher- 第三方应用图标替换
    resource-color 的引用
    java学习笔记——IO流部分
    二进制基础
    java学习笔记——IO部分(遍历文件夹)
    Java线程:线程的同步与锁
    AWT与Swing的区别
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/20201016day37.html
Copyright © 2011-2022 走看看