【数论】本原勾股数

筛选出所有范围的勾股数 a2+b2=c2 a 2 + b 2 = c 2 的方法:
(1)找出所有的本原勾股数
(2)对所有本原勾股数翻倍仍然构成一个勾股数

1. 定理

首先这种本原勾股数是无限的,构造方法是:
a=st a = s ∗ t
b=s2t2 b = s 2 − t 2
c=s2+t2 c = s 2 + t 2
其中,s>t>=1 ,s和t是没有因数的奇数{ ((gcd(s,t) ==t ) && (s&1) && (t&1) ) } { ((gcd(s,t) ==t ) && (s&1) && (t&1) ) }

2.例题 HDU6441 Find Integer

#include
using namespace std;
#define ll long long
const int mod=998244353;
const int MAXN=400000+10;
const int MAXM=4000+10;
const int INF=0x3f3f3f3f;

struct Node
{
    ll b,c;
    bool flag;
}aa[MAXN];

void init()
{
    ll x1,x2,x3;
    for(ll s=1;s<=40000;s+=2)
    {
        for(ll t=1;t<s;t+=2)
        {
            if(__gcd(s,t)!=1)break;
            x1=s*t;
            if(x1>40000)break;
            x2=(s*s-t*t)/2;
            x3=(s*s+t*t)/2;
            if((x1&1)==0||(x2&1)==1)break;
            aa[x1].b=x2;aa[x1].c=x3;aa[x1].flag=true;
            if(x2<=40000)
            {
                aa[x2].b=x1;aa[x2].c=x3;
                aa[x2].flag=true;
            }
            for(ll i=1;i*x1<=40000;i++)
            {
                aa[i*x1].b=x2*i;
                aa[i*x1].c=x3*i;
                aa[i*x1].flag=true;
                if(x2*i<=40000)
                {
                    aa[i*x2].b=i*x1;
                    aa[i*x2].c=i*x3;
                    aa[i*x2].flag=true;
                }
            }
        }
    }

}

int main()
{
    int t;
    scanf("%d",&t);
    ll a,n;
    init();
//    for(int i=1;i<=40000;i++)
//    {
//            cout<"  "<//    }
    while(t--)
    {
        scanf("%lld%lld",&n,&a);
        if(n==0||n>2)
        {
            printf("-1 -1\n");
        }
        else if(n==1)
        {
            printf("%lld %lld\n",(ll)1,a+1);
        }
        else
        {
            if(aa[a].flag)
            {
                printf("%lld %lld\n",aa[a].b,aa[a].c);
            }
            else
                printf("-1 -1\n");
        }
    }


    return 0;
}

你可能感兴趣的:(1.5.1,数论数学初步)