[HAOI2008] 圆上的整点 - 数论

给定圆 \(x^2+y^2=r^2\),求圆周上有多少个点的坐标是整数。 \(r\leq 2\times 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;
}

猜你喜欢

转载自www.cnblogs.com/mollnn/p/12388367.html