简略题意:给出 2k 个数v,求出 (xi,yi,zi) 满足 xi<yi<zi<1e9 的所有本源勾股组之后, 问∑v[yi%(2k)] 的答案是多少。
本源勾股组的构造:
找出
m,n(m>n)满足x=m2−n2,y=2mn,z=m2+n2,(x,y,z)
即为勾股组。若
m
和
所以我们找到
m2+n2
的所有互质的
m和n
即可,而这点我们可以用法里数列来构造得到,构造得到的勾股组个数有
159154994
这么多。
所以预处理找到所有y,然后统计即可。
我本地是没有跑出来的…然后在cf上跑了出来,耗时2640ms,比杭电快了1s左右。
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
const long double eps = 1e-8;
//int dcmp(long double x) { if(_abs(x)<=eps) return 0; return (x>0)?1:-1;};
typedef long long LL;
long double _abs(long double x) {
return x<0?-x:x;
}
namespace solver {
int t, k;
int v[(1<<17)+2];
LL ans[(1<<17)+2];
const int maxn = 1<<17;
int cnt = 0;
void dfs(int lu, int ld, int ru, int rd) {
int mu = lu + ru;
int md = ld + rd;
if(1LL*md*md+1LL*mu*mu > (int)1e9) return;
if((mu-md)&1)
ans[max(md*md-mu*mu, 2*md*mu)&(maxn-1)]++, cnt++;
dfs(lu, ld, mu, md);
dfs(mu, md, ru, rd);
}
void solve() {
scanf("%d", &t);
dfs(0, 1, 1, 1);
while(t--) {
scanf("%d", &k);
for(int i = 0; i < (1<<k); i++)
scanf("%d", &v[i]);
LL res = 0;
for(int i = 0; i < maxn; i++)
res += ans[i] * v[i&((1<<k)-1)];
printf("%lld\n", res);
}
}
}
int main() {
solver::solve();
return 0;
}