[HAOI2008]圆上的整点

Posted wolfycz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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=R^2)

(Y^2=(R-X)(R+X))

(d=gcd(R-X,R+X),A=dfrac{R-X}{d},B=dfrac{R+X}{d})

所以(y^2=d^2 imes A imes B)

因为(y^2,d^2)为完全平方数,因此(A imes B)也为完全平方数

由于(gcd(A,B)=1),因此(A,B)本身也是完全平方数

(a^2=A,b^2=B),由于(gcd(A,B)=1),因此(A e B),因此(a e b)

我们令(a<b),则可以得到(a^2=dfrac{R-X}{d},b^2=dfrac{R+X}{d})

相加可得(a^2+b^2=dfrac{2R}{d}),因此(d)(2R)的约数

于是我们可以在(sqrt{2R})的时间内枚举其约数,由于(2a^2<dfrac{2R}{d}),因此我们可以直接枚举(ain[1,sqrt{dfrac{R}{d}}]),然后计算出(b),再将其反代回求出(A,B),判断(A,B)是否满足条件

但是这样子我们只算出了处于第一象限的答案,根据圆的对称性,我们需要将答案乘上4,并且加上坐标轴上的4个点

/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
    static char buf[1000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
    int x=0,f=1; char ch=gc();
    for (;ch<'0'||ch>'9';ch=gc())   if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0';
    return x*f;
}
inline int read(){
    int x=0,f=1; char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar())  if (ch=='-')    f=-1;
    for (;ch>='0'&&ch<='9';ch=getchar())    x=(x<<3)+(x<<1)+ch-'0';
    return x*f;
}
inline void print(int x){
    if (x<0)    putchar('-'),x=-x;
    if (x>9)    print(x/10);
    putchar(x%10+'0');
}
ll R,Ans;
ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
bool check(int a,int b){
    ll A=1ll*a*a,B=1ll*b*b;
    return (gcd(A,B)==1)&&(A!=B);
}
void work(ll x){
    for (int a=1;a*a<=x>>1;a++){
        int b=trunc(sqrt(x-a*a));
        if (1ll*a*a+1ll*b*b!=x) continue;
        if (check(a,b)) Ans++;
    }
}
int main(){
    R=2ll*read();
    for (int i=1;1ll*i*i<=R;i++){
        if (R%i)    continue;
        work(i);
        if (R/i!=i) work(R/i);
    }
    printf("%lld
",4*Ans+4);
}

以上是关于[HAOI2008]圆上的整点的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1041 [HAOI2008]圆上的整点

[HAOI2008]圆上的整点

BZOJ 1041: [HAOI2008]圆上的整点数论,解方程

bzoj 1041: [HAOI2008]圆上的整点

[HAOI2008]圆上的整点

[BZOJ]1045 圆上的整点(HAOI2008)