BZOJ4544 椭圆上的整点(数论)

本文深入探讨了一种基于数论的算法实现,通过分析2n=d(a2+3b2)的数学模型,提出了一种枚举d和b的解决方案,以此来解决特定的数论问题。算法首先计算d=gcd(n-x,n+x),然后通过枚举d和b来求解,最终复杂度较为合理。

  https://www.cnblogs.com/Gloid/p/9538413.html 基本思路没有太大差别。得到2n=d(a2+3b2),其中d=gcd(n-x,n+x),n-x==a2&&n+x==3b2||n-x==3a2&&n+x==b2。于是枚举d,然后枚举b。复杂度玄学。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
ll gcd(ll n,ll m){return m==0?n:gcd(m,n%m);}
int T;ll n,m;
bool issqr(ll n){return (ll)(sqrt(n))*(ll)(sqrt(n))==n;}
int calc(ll n,ll d)
{
    int s=0;
    for (int i=1;d*i*i<=n;i++)
    {
        ll b=1ll*i*i,a=m/d-b;
        if (a%3==0&&issqr(a/3)&&gcd(a,b)==1) s++;
    }
    for (int i=1;3*d*i*i<=n;i++)
    {
        ll b=3ll*i*i,a=m/d-b;
        if (issqr(a)&&gcd(a,b)==1) s++;
    }
    return s;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("bzoj4544.in","r",stdin);
    freopen("bzoj4544.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    T=read();
    while (T--)
    {
        cin>>n;m=n<<1;
        int ans=0;
        for (int d=1;1ll*d*d<=m;d++)
        if (m%d==0)
        {
            ans+=calc(n,d);
            if (m/d!=d) ans+=calc(n,m/d);
        }
        ans*=4;ans+=2;
        cout<<ans<<endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Gloid/p/9887012.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值