[HAOI2008] 圆上的整点

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

Solution

将原式化为 (y^2=r^2-x^2=(r-x)(r+x)),设 (u,v s.t. r-x=du, r+x=dv, (u,v)=1),则 (y^2=d^2uv),于是 (uv) 必然是完全平方数,故可设 (u=s^2,v=t^2),则有 (y^2=d^2s^2t^2)

只考虑第一象限内的部分,设答案为 (ans),那么原问题答案就是 (4(ans+1))

考虑如何计算 (ans),由 (r-x=du,r+x=dv) 解得 (x=frac{t^2-s^2}{2}d, 2r=(t^2+s^2)d),于是我们可以暴力枚举 (2r) 的约数 (d),枚举每一个 (s),算出其对应的 (t),然后计算出 (x,y) 看其是否合法来统计贡献

#include <bits/stdc++.h>
using namespace std;

#define int long long
int r;

signed main() {
    int ans=0;
    cin>>r;
    for(int i=1;i*i<=2*r;i++) if(2*r%i==0) {
        int d=i;
        for(int s=1;s*s<=2*r/d;s++) {
            int t=sqrt(2*r/d-s*s);
            if(__gcd(s,t)!=1) continue;
            if((t*t+s*s)==2*r/d) {
                int x=(s*s-t*t)/2*d;
                int y=d*s*t;
                if(x>0&&y>0&&x*x+y*y==r*r) ans+=2;
            }
        }
        if(i*i==2*r) continue;
        d=2*r/i;
        for(int s=1;s*s<=2*r/d;s++) {
            int t=sqrt(2*r/d-s*s);
            if(__gcd(s,t)!=1) continue;
            if((t*t+s*s)==2*r/d) {
                int x=(s*s-t*t)/2*d;
                int y=d*s*t;
                if(x>0&&y>0&&x*x+y*y==r*r) ans+=2;
            }
        }
    }
    cout<<4*(ans+1)<<endl;
}

原文地址:https://www.cnblogs.com/mollnn/p/12388367.html