Problem Description
Given a list of integers
a0,a1,a2,⋯,a2k−1
. Pythagoras triples over
109
are all solutions of
x2+y2=z2
where
x,y
and
z
are constrained to be positive integers less than or equal to
109
. You are to compute the sum of
ay mod 2k
of triples
(x,y,z)
such that
x<y<z
and they are relatively prime, i.e., have no common divisor larger than
1
.
Input
The first line is an integer
T (1≤T≤3)
indicating the total number of cases.
For each test case the first line is the integer k (1≤k≤17) .
The second line contains 2k integers corresponding to a0 to a2k−1 , where each ai satisfies 1≤ai≤255 .
For each test case the first line is the integer k (1≤k≤17) .
The second line contains 2k integers corresponding to a0 to a2k−1 , where each ai satisfies 1≤ai≤255 .
Output
For each case output the sum of
ay mod 2k
in a line.
Sample Input
3 2 0 0 0 1 2 1 0 0 0 2 1 1 1 1
Sample Output
39788763 79577506 159154994
题意:
此题首先要求求有多少组 (x, y, z)
满足 gcd(x, y) = gcd(x, z) = gcd(y, z) = gcd(x, y, z) = 1
且
x,y,z≤109
。上述描述即求有多少组本原勾股数 或 素勾股数 (x, y, z)
满足
x,y,z≤109
。
思路:
本原勾股数 a*a+b*b=c*c,当且仅当 a=i*i-j*j,b=2*i*j,c=i*i+j*j,(i和j为互质且一奇一偶的任意正整数)
我们枚举i和j,打表即可。
//
// main.cpp
// 1006
//
// Created by zc on 2017/9/20.
// Copyright © 2017年 zc. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1000000000;
const int MOD=(1<<17)-1;
int p[20],d[MOD+1],a[MOD+1];
void init()
{//本原勾股数 a*a+b*b=c*c, 当且仅当 a=i*i-j*j,b=2*i*j,c=i*i+j*j,(i和j为互质且一奇一偶的任意正整数)
for(int i=1;i*i<=N;i++)//由c<=1e9,i*i<=1e9
{
int cnt=0,t=i;
for(int j=2;j*j<=t;j++)//求i的素因子
{
if(!(t%j))
{
p[++cnt]=j;
while(!(t%j)) t/=j;
}
}
if(t!=1) p[++cnt]=t;
int c=i*i,k;//c=i*i+j*j<1e9
for(int j=1;j<i;j++)
{
c+=j+j-1;
if(c>N) break;
if(!((i-j)&1)) continue;
for(k=1;k<=cnt;k++)//判断互质
if(!(j%p[k])) break;
if(k>cnt)
d[max(i*i-j*j,2*i*j)&MOD]++;
}
}
}
int main(int argc, const char * argv[]) {
init();
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i< 1<<n;i++) scanf("%d",&a[i]);
ll ans=0;
int k=(1<<n)-1;
for(int i=0;i<=MOD;i++)
ans+=(ll)a[i&k]*d[i];
printf("%lld\n",ans);
}
}
xdwa