HDU 6211 Pythagoras(本原勾股数)

本文探讨了如何通过数学证明及编程实现来寻找特定条件下的勾股数,并提供了一个具体的算法解决方案,包括代码示例。

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

Description

给出一长度为2n2n的序列a0,...,a2n1a0,...,a2n−1,求ay mod 2n∑ay mod 2n,其中yy满足存在x<y<z109,(x,y,z)=1使得x2+y2=z2x2+y2=z2

Input

第一行输入一整数TT表示用例组数,每组用例首先输入一整数n,之后输入a0,...,a2n1a0,...,a2n−1

(1T3,1n17,1ai255)(1≤T≤3,1≤n≤17,1≤ai≤255)

Output

ay mod 2n∑ay mod 2n

Sample Input

3
2
0 0 0 1
2
1 0 0 0
2
1 1 1 1

Sample Output

39788763
79577506
159154994

Solution

只要找出所有不超过109109的本原勾股数即可,对于一组本原勾股数x2+y2=z2x2+y2=z2,先证明几个结论

1.xx​yy​互素

d=(x,y)>1d=(x,y)>1,由z2=x2+y2z2=x2+y2d2|z2d2|z2,即d|zd|z,进而d|(x,y,z)=1d|(x,y,z)=1,矛盾,故(x,y)=1(x,y)=1

2.x,yx,y一奇一偶

由结论11知,如果x,y不是一奇一偶则必然为两个奇数,进而zz为偶数,假设x=2a+1,y=2b+1,z=2c,由x2+y2=z2x2+y2=z24a2+4a+1+4b2+4b+1=4c24a2+4a+1+4b2+4b+1=4c2,即a2+b2c2+a+b=12a2+b2−c2+a+b=12,矛盾,故x,yx,y一奇一偶

3.存在奇偶性不同的两个数s,ts,t满足s>t,(s,t)=1s>t,(s,t)=1x=s2t2,y=2st,z=s2+t2x=s2−t2,y=2st,z=s2+t2

假设xx为奇数,y为偶数,则zz必然为奇数,x2=z2y2=(zy)(z+y),首先证明d=(z+y,zy)=1d=(z+y,z−y)=1

由于z+y,zyz+y,z−y均为奇数,故dd为奇数,由于d|(z+y+zy)=2z,d|((z+y)(zy))=2y,故d|y,d|zd|y,d|z,且注意到d2|(z+y)(zy)=x2d2|(z+y)(z−y)=x2,故d|xd|x,进而d|(x,y,z)=1d|(x,y,z)=1

由于z+yz+yzyz−y互素,故z+y,zyz+y,z−y为两个互素的完全平方数,设z+y=m2,zy=n2z+y=m2,z−y=n2,则x=mn,y=m2n22,z=m2+n22x=mn,y=m2−n22,z=m2+n22,其中m,nm,n均为奇数且m>n,(m,n)=1m>n,(m,n)=1

s=m+n2,t=mn2s=m+n2,t=m−n2,则s>ts>t均为正整数,且由于s+t=m,st=ns+t=m,s−t=n,故(s+t,st)=1(s+t,s−t)=1,进而(s,t)=1(s,t)=1,而s+t=ms+t=m为奇数,显然s,ts,t一奇一偶,而代入即得x=s2t2,y=2st,z=s2+t2x=s2−t2,y=2st,z=s2+t2

由结论33,只要枚举所有的(s,t)即可得到所有的本原勾股数,而由于z=s2+t2109z=s2+t2≤109,故只需要枚举小范围的ss,然后找小于s、与ss奇偶性不同且与s互素的tt即可

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
const int mod=(1<<17)-1;
int T,n,a[mod+5],f[mod+5];
void init(int N=1e9)
{
    int p[33];
    for(int i=1;i*i<=N;i++)
    {
        int res=0,ii=i;
        for(int j=2;j*j<=ii;j++)
            if(ii%j==0)
            {
                p[res++]=j;
                while(ii%j==0)ii/=j;
            }
        if(ii>1)p[res++]=ii;
        int c=i*i;
        for(int j=1;j<i;j++)
        {
            c+=2*j-1;
            if(c>N)break;
            if(!((i-j)&1))continue;
            int k=0;
            while(k<res&&j%p[k]!=0)k++;
            if(k==res)f[max(i*i-j*j,2*i*j)&mod]++;
        }
    }
}
int main()
{
    init();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        n=(1<<n)-1;
        for(int i=0;i<=n;i++)scanf("%d",&a[i]);
        ll ans=0;
        for(int i=0;i<=mod;i++)ans+=(ll)a[i&n]*f[i];
        printf("%I64d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值