[bzoj1041] [洛谷P2508] [HAOI2008] 圆上的整点
Posted 秋千旁的蜂蝶~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj1041] [洛谷P2508] [HAOI2008] 圆上的整点相关的知识,希望对你有一定的参考价值。
Description
求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
Input
只有一个正整数n,n<=2000 000 000
Output
整点个数
Sample Input
4
Sample Output
4
想法
嗯哼,一道数学题。
开始推柿子。
首先我们只需求出满足 $ x^2 + y^2 = z^2 $ 的正整数对数即可,乘以4后再加4便为答案
\[
x^2+y^2=z^2 \y^2=z^2-x^2=(z+x)(z-x) \设\quad d=gcd(z+x,z-x) \那么 \quad y^2=d^2 \frac{z+x}{d} \frac{z-x}{d} \这里面 \frac{z+x}{d} 与 \frac{z-x}{d} 互质,所以 \frac{z+x}{d} 和 \frac{z-x}{d} 都为完全平方数 \设 \frac{z+x}{d}为A, \frac{z-x}{d}为B \设A=a^2,B=b^2 \a^2+b^2=\frac{2z}{d} \故,我们可以枚举2z的每一个约数d,然后再枚举每一对满足a^2+b^2=\frac{2z}{d}的a和b \得到a,b后要带回去算出A,B,判断是否gcd(A,B)=1且A \neq B
\]
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll n,m,ans=0;
ll gcd(ll a,ll b) { return b ? gcd(b,a%b) : a; }
int main()
{
scanf("%d",&n);
m=sqrt(n*2);
for(ll d=1;d<=m;d++){
if((n*2)%d) continue;
for(ll a=1;a*a*2<=d;a++){
ll b=sqrt(d-a*a);
if(b*b!=d-a*a) continue;
ll A=a*a,B=b*b;
if(gcd(A,B)!=1 || A==0 || B==0 || A==B) continue;
ans+=4;
}
for(ll a=1;a*a*2<=n*2/d;a++){
ll b=sqrt(n*2/d-a*a);
if(b*b!=n*2/d-a*a) continue;
ll A=a*a,B=b*b;
if(gcd(A,B)!=1 || A==0 || B==0 || A==B) continue;
ans+=4;
}
}
printf("%lld\n",ans+4);
return 0;
}
以上是关于[bzoj1041] [洛谷P2508] [HAOI2008] 圆上的整点的主要内容,如果未能解决你的问题,请参考以下文章