LOADING

加载过慢请开启缓存 浏览器默认开启

补题

2024/9/16

[P2508 HAOI2008] 圆上的整点 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析:

$y2=r2-x^2=(r-x)(r+x) $

d=gcd(rx,r+x),rx=ud,r+x=vdd=gcd(r-x,r+x),r-x=u*d,r+x=v*d

则原式变为:y2=d2uvy^2=d^2*u*v

则可以列出两个等式:

x=vu2d,2r=(u+v)dx=\frac{v-u}{2}d,2r=({u+v})d

枚举2r的约数d并枚举u可以在o(r+2rd)o(\sqrt{r}+\sum\frac{2r}{d})解决该问题,显然时间复杂度不能接受

注意到u,v互质并且等式左边为平方数则u,v为平方数:

不妨设u=s2,v=t2u=s^2,v=t^2

则等式变为:x=t2s22d,2r=(s2+t2)dx=\frac{t^2-s^2}{2}d,2r=(s^2+t^2)d

此时枚举2r的约束d并枚举s可以在o(r+2rd)o(\sqrt{r}+\sum \sqrt\frac{2r}{d})求解

r数的约数可以粗略估计为2102^{10}最大不会超过r,所以最大时间复杂度为o(r210)o(\sqrt{r}*2^{10}) 约为31073*10^7

(实际远比这个小)

int ans,R;
void get(int d,int r){
    // cout<<d<<" "<<r<<"\n";
    for(int i=1;i<=r/i;i++){
        int s=i,t=sqrt(r-i*i);
        if(s*s+t*t!=r||__gcd(s,t)!=1)continue;
        int x=(t*t-s*s)/2*d,y=d*s*t;
        // cout<<x<<" "<<y<<"\n";
        if(x>0&&y>0&&x*x+y*y==(R/2)*(R/2))ans+=2;
    }
}
void solve(){
    int r;cin>>r;
    r<<=1;
    R=r;
    for(int i=1;i<=r/i;i++){
        if(r%i==0)get(i,r/i);
        if(r%i==0&&i*i!=r)get(r/i,r/(r/i));
    }
    cout<<(ans+1)*4<<"\n";
}