【BZOJ】 1041: [HAOI2008]圆上的整点

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1041


${x^{2}+y^{2}=r^{2} }$

${Rightarrow y^{2}=(r-x)(r+x)}$

令${d=gcd(r-x,r+x)}$

则${y^{2}=d^{2}*frac{r+x}{d}*frac{r-x}{d}}$

再令${A=frac{r+x}{d}}$,${B=frac{r-x}{d}}$

则${y^{2}=d^{2}*A*B}$

考虑${y^{2}}$是完全平方数,${d^{2}}$是完全平方数,又${gcd(A,B)=1}$那么${A,B}$都是完全平方数。

设${A=a^{2}}$,${B=b^{2}}$

${A+B=a^{2}+b^{2}}$

${Rightarrow frac{2*r}{d}=a^{2}+b^{2}}$

  考虑枚举${frac{2*r}{d}}$,这一步的复杂度是${O(sqrt{r})}$的,然后再在${left [ 1,sqrt{2*frac{r}{d}}/2 ight ]}$的范围内枚举${a}$,进而可以算出${A,b,B}$,然后判断${A,B}$是否互质,$B$是否为完全平方数,这样子就算出了第一象限的答案,然后将$ans*4+4$,算是统计了每一个象限的并且加上了坐标轴上的四个点。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 using namespace std;
11 #define llg long long
12 #define maxn 100010
13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
14 llg ans,n;
15 inline llg getint()
16 {
17     llg w=0,q=0; char c=getchar();
18     while((c<'0' || c>'9') && c!='-') c=getchar();
19     if (c=='-')  q=1, c=getchar(); while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
20     return q ? -w : w;
21 }
22 
23 void calc(llg d)
24 {
25     for (llg a=1;a<=sqrt(d/2);a++)
26     {
27         llg A=a*a,B=d-A,b=sqrt(B);
28         if (b*b==B && __gcd(A,B)==1 && A!=B) ans++;
29     }
30 }
31 
32 int main()
33 {
34     yyj("circle");
35     cin>>n;
36     for (llg i=1;i<=sqrt(n*2);i++)
37         if ((2*n%i)==0)
38         {
39             calc(i);
40             calc(2*n/i);
41         }
42     cout<<ans*4+4;
43     return 0;
44 }
原文地址:https://www.cnblogs.com/Dragon-Light/p/6744132.html