码迷,mamicode.com
首页 > 其他好文 > 详细

[bzoj1041] [洛谷P2508] [HAOI2008] 圆上的整点

时间:2018-04-24 23:17:19      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:判断   inpu   printf   for   有一个   type   span   lld   数学   

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] 圆上的整点

标签:判断   inpu   printf   for   有一个   type   span   lld   数学   

原文地址:https://www.cnblogs.com/lindalee/p/8934217.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!