题意:给出R,问半径为R的圆上有多少个整数点? R<=2e9.
x^2+y^2=r^2. -> (r+x)(r-x)=y^2 . 令d=gcd(r+x,r-x).m=(r+x)/d,n=(r-x)/d.
则y^2= d^2*m*n . 因为gcd(m,n)=1 所以m,n都为完全平方数.(m,n素因子分解后的幂都为偶数.)
那么让m=u^2,n=v^2. 得:r+x=d*u^2,r-x=d*v^2. 相加后得: 2r=d(u^2+v^2).
d为2r的约束. Sqrt(2r)内枚举d 然后在Sqrt(2r/d)内枚举u即可.得到(u,v,d)就能确定一组(x,y) .注意gcd(u,v)=1.
先将R做素因子分解.R^2=p1^q1 * ...pk^qk.
若p mod 4 = 1 那么它可以拆成一组共轭高斯素数相乘.
若p mod 4 = 3 那么这个p不能被拆分.
每个p拆分成(a+bi)*(a-bi) 分成左右两列.分别放互为共轭的复数.
最后两列结果分别为(A+Bi)(A-Bi). A^2+B^2=R^2.
x^2+y^2=r^2. -> (r+x)(r-x)=y^2 . 令d=gcd(r+x,r-x).m=(r+x)/d,n=(r-x)/d.
则y^2= d^2*m*n . 因为gcd(m,n)=1 所以m,n都为完全平方数.(m,n素因子分解后的幂都为偶数.)
那么让m=u^2,n=v^2. 得:r+x=d*u^2,r-x=d*v^2. 相加后得: 2r=d(u^2+v^2).
d为2r的约束. Sqrt(2r)内枚举d 然后在Sqrt(2r/d)内枚举u即可.得到(u,v,d)就能确定一组(x,y) .注意gcd(u,v)=1.
因为上面算的只是第一象限内的点.答案乘4后+4个坐标轴上的点即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll R;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
int main()
{
cin>>R;
R*=2;
ll res=0;
for(ll i=1;i*i<=R;i++)
{
if(R%i) continue;
ll t=R/i;
for(ll u=1;u*u<=t;u++)
{
ll v=sqrt(t-u*u);
if(v<=u) break;
if(v*v+u*u!=t) continue;
if(gcd(u,v)==1) res++;
}
if(i*i==R) break;
t=i;
for(ll u=1;u*u<=t;u++)
{
ll v=sqrt(t-u*u);
if(v<=u) break;
if(v*v+u*u!=t) continue;
if(gcd(u,v)==1) res++;
}
}
res*=4;
res+=4;
cout<<res<<'\n';
return 0;
}
mark
圆上的整数点(a,b)满足 a^2+b^2=R^2.
等价于在复平面上有多少个z=a+bi 满足(a+bi)*(a-bi)=a^2+b^2 =R^2先将R做素因子分解.R^2=p1^q1 * ...pk^qk.
若p mod 4 = 1 那么它可以拆成一组共轭高斯素数相乘.
若p mod 4 = 3 那么这个p不能被拆分.
每个p拆分成(a+bi)*(a-bi) 分成左右两列.分别放互为共轭的复数.
最后两列结果分别为(A+Bi)(A-Bi). A^2+B^2=R^2.
总共选法为4*(q1+1)*...(qk+1). qi都为mod4==1的素数. 4为复数乘上1,-1,i,-i.