BZOJ 1041 HAOI2008 圆上的整点

1041: [HAOI2008]圆上的整点

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4626  Solved: 2083
[Submit][Status][Discuss]

Description

求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。

Input

只有一个正整数n,n<=2000 000 000

Output

整点个数

Sample Input

4

Sample Output

4

HINT

Source

 这里先只考虑x,y都大于0的情况

如果x^2+y^2=r^2,则(r-x)(r+x)=y*y

令d=gcd(r-x,r+x),r-x=d*u^2,r+x=d*v^2,显然有gcd(u,v)=1且u<v

有2r=d*(u^2+v^2),y=d*u*v,x=d(v^2-u^2)/2

枚举2r的约数d,再花费sqrt(2r/d)的时间枚举u,求出v=sqrt(2r/d-u^2)然后判断gcd(u,v)=1

最后结果乘以4(四个象限)+4(坐标轴上)即可
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll ans,r,rr,d;
 5 inline ll gcd(ll xx,ll yy){
 6     while(yy) {ll t=xx;xx=yy;yy=t%yy;}
 7     return xx;
 8 }
 9 inline void solve(ll xx){
10     for(ll i=1;i<=sqrt(1.0*xx);i++){
11         ll t=int(sqrt(1.0*(xx-i*i)+0.5));
12         if(i>=t) break;
13         if(1ll*t*t+1ll*i*i==1ll*xx&&gcd(i,t)==1) ans++;
14     }
15 }
16 int main(){
17     //freopen("All.in","r",stdin);
18     //freopen("a.out","w",stdout);
19     cin>>r;
20     rr=r<<1;
21     ans=1;
22     for(ll i=1;i<=sqrt(1.0*rr);i++){
23         if(rr%i!=0) continue;
24         solve(rr/i);
25         if(i*i==rr) break;
26         solve(i);
27     }
28     cout<<ans*4<<endl;
29     return 0;
30 }
代码

 

posted @ 2017-11-19 16:06  zhangenming  阅读(85)  评论(0编辑  收藏