正题
题目链接:https://www.luogu.com.cn/problem/P2508
题目大意
一个在(0,0)(0,0)(0,0)的圆心,半径为rrr,求圆有多少个整点。
1≤r≤2×1091\leq r\leq 2\times 10^91≤r≤2×109
解题思路
设这个点为(x,y)(x,y)(x,y),那么有x2+y2=r2x^2+y^2=r^2x2+y2=r2
x2=r2−y2=(r+y)(r−y)x^2=r^2-y^2=(r+y)(r-y)x2=r2−y2=(r+y)(r−y)
设r+y=a×d,r−y=b×d,gcd(a,b)=1r+y=a\times d,r-y=b\times d,\gcd(a,b)=1r+y=a×d,r−y=b×d,gcd(a,b)=1,因为x2x^2x2为完全平方数,所以a=u2,b=v2a=u^2,b=v^2a=u2,b=v2
x2=u2v2d2⇒x=u×v×dx^2=u^2v^2d^2\Rightarrow x=u\times v\times dx2=u2v2d2⇒x=u×v×d
2r=(v2+u2)×d2r=(v^2+u^2)\times d2r=(v2+u2)×d
所以我们枚举2r2r2r的因数ddd,然后再枚举一个v2v^2v2就行了。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll n,m,r,ans;
void solve(ll d){for(ll s=1;s*s<=r/d;s++){ll t=sqrt(r/d-s*s);if(s*s+t*t!=r/d)continue;if(__gcd(s,t)>1)continue;ll x=(s*s-t*t)/2ll*d;ll y=t*s*d;if(x>0&&y>0&&x*x+y*y==r/2ll*r/2ll)ans+=2;}return;
}
signed main()
{scanf("%lld",&r);r=r*2ll;for(ll i=1;i*i<=r;i++)if(r%i==0){solve(i);if(i*i!=r)solve(r/i);}printf("%lld\n",(ans+1)*4ll);return 0;
}