LOADING

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

补题

2024/9/16

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

分析:

$y^2=r^2-x^2=(r-x)(r+x) $

设$d=gcd(r-x,r+x),r-x=ud,r+x=vd$

则原式变为:$y^2=d^2uv$

则可以列出两个等式:

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

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

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

不妨设$u=s^2,v=t^2$

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

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

r数的约数可以粗略估计为$2^{10}$最大不会超过r,所以最大时间复杂度为$o(\sqrt{r}2^{10})$ 约为$310^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";
}