洛谷P2508 [HAOI2008]圆上的整点
结论题 数学
做这道题之前首先要知道勾股方程的通解
勾股方程:\(x^2+y^2=r^2\)的通解为x = \(d*\frac{a^2-b^2}{2}\), y = \(d*a*b\), r = \(d*\frac{a^2+b^2}{2}\)
其中a, b为互质的正整数,d为任意实数
其实也就是勾股数乘上一定的倍数,简化:
x = \(\frac{a^2-b^2}{2}\), y = \(a*b\), r = \(\frac{a^2+b^2}{2}\)
然后我们考虑使得x, y为正整数的方程的解,此时d为正整数且为2r的约数,我们只需枚举2r的约数,然后枚举有多少个满足条件的\(a^2+b^2\)即可
因为x>0,故a>b,因此我们只需要枚举\(\sqrt{\frac{r}{d}}\)个b即可,若a,b互质且\(a^2+b^2=\frac{2*r}{d}\),令ans++。
最后原题要求x,y的整数解,(x,y)可以在4个象限中,再加上坐标轴上的四个点,最终答案为ans*4+4
#include<bits/stdc++.h>
using namespace std;
#define go(i,a,b) for(int i=a;i<=b;++i)
#define int long long
int r,ans;
int gcd(int a,int b){ return b?gcd(b,a%b):a; }
void calc(int d){
int x=2*r/d,i;
for(i=1;i*i*2<x;++i){
int t=x-i*i,j=sqrt(t);
if(j*j==t&&gcd(i,j)==1) ++ans;
}
}
void work(){
for(int i=1;i*i<=2*r;++i){
if(2*r%i) continue;
calc(i);
if(2*r/i!=i) calc(2*r/i);
}
}
signed main(){
cin>>r;
work();
cout<<ans*4+4;
return 0;
}