1041: [HAOI2008]圆上的整点

本文详细解析了一道数论题目,并通过运用gcd和分解质因数的方法进行优化。介绍了如何利用数学公式推导出更高效的算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数论题无力Orz...看了下题解,所以总结下吧,主要是运用gcd和分解质因数来进行优化。。

觉得写得很好,所以把题解搬过来了=。=

首先让我们一起来推下公式:

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

到这里为止应该都很容易想到,接下来是关键

设d=gcd(r-x,r+x)
设r-x=d*A
   r+x=d*B
   y^2=d^2*AB

解释下,d已被提出,所以gcd(A,B)=1
而进一步,因为y^2=d^2*A*B,而gcd(A,B)=1
所以,我们可以这样表示:
A=a*a
B=b*b
(a<>b)
(因为y^2是平方数,d^2是平方数,所以可以这样化过来)

∴ r-x=d*a^2  
     r+x=d*b^2  

①+②得 2r=d*(a^2+b^2)

d是2r的约数,所以我们可以用sqrt(2r)的时间枚举d,求出好多对d
我们设
d=d
d0=(2r)/d

我们可以用(sqrt(d)+sqrt(d0))的时间来枚举a,求出b,来对这一对d求解

思路应该清晰了吧
下面讲讲细节:
1041: <wbr>[HAOI2008]圆上的整点
我们枚举的其实只是第一象限的答案,而还缺少坐标轴上的4个点
所以最后   ans=ans*4+4  (注意 不是ans*2+4,下面解释)

还有一个细节,在枚举a时实际的枚举范围是 a^2*2<2r/d
我们可以举一个例子
在r=1225中
我们可以算出的其中2个解为
d=490 a=1 b=2
d=490 a=2 b=1
没错,看起来好像a,b倒了一下,不一样
实际算到y中时
y^2=d(a^2+b^2)却成了同一个解
有些题解中最后会是*2而不是*4,就是因为这样(比如当年wjh大神给我们的题解)
这实际是写题解的人自己凑出,没搞清楚,或是没写清造成的

代码什么的就上我自己的好了(格式好乱)

#include<cmath>
#include<cstdio>
using namespace std;
long long r;
long long gcd(long long a,long long b)
{
    return b==0?a:gcd(b,a%b);
}
int cal(int d)
{
    int answer=0;
    int d0=r/d;
    for(int a=1;a*a*2<=d0;a++)
    {
        double tmp=sqrt(d0-a*a);
        if(tmp==floor(tmp))
        {
            int b=(int)tmp;
            if(gcd(a,b)==1 && a!=b) answer++;
        }
    }
    return answer;
}
int main()
{
    int ans=0;
    scanf("%d",&r);
    r*=2;
    for(int i=1;i<=r/i;i++)
    {
        if(r%i==0)
        {
            if(r/i!=i) 
            ans=ans+cal(i)+cal(r/i);
            else ans+=cal(i);
        }
    }
    printf("%d",ans*4+4);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值