20201016day37 刷题记录

1 [HAOI2008]圆上的整点

problem

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

solution

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

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

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

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

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

\[Y^2=d^2\times A \times B \]

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

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

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

\((3)+(4)\)得:

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

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

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

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

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

因为这样只算出了第一象限的情况<上面枚举时均是从1开始枚举>,根据圆的对称性,其他象限的整点数与第一象限中的整点数相同,最后,在象限轴上的4个整点未算,加上即可,那么最后答案为\(ans=4\times\text{第一象限整点数}+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\n",ans*4+4);
      return 0;
}

圆内整点

posted @ 2020-10-16 10:29  刘子闻  阅读(148)  评论(0编辑  收藏  举报