[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] 圆上的整点的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P1041 传染病控制

洛谷 P1041 传染病控制

洛谷P1041 传染病控制

传染病控制(洛谷 1041 WA 90)

洛谷CON1041 NOIP模拟赛一试

[NOIP2003] 提高组 洛谷P1041 传染病控制