zoukankan      html  css  js  c++  java
  • [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);
    }
    
  • 相关阅读:
    并发控制-CycliBarrier
    并发控制-条件对象(Condition接口)
    并发控制-信号量(Semaphore)
    控制并发-CountDownLatch
    控制并发流程
    [杂谈]重新认识RDD
    【杂谈】RDD-运行-2
    【杂谈】RDD-依赖
    [杂谈]Executor-1
    [杂谈]Rdd运行-1
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10003263.html
Copyright © 2011-2022 走看看