您的位置:首页 > 编程语言 > Go语言

[HDU 6211] Pythagoras

2017-09-20 16:59 162 查看
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6211

题目大意: T组数据, 输入一个长度为2k的数组a,求∑(x,y,z)ay % 2k, 其中x<y<z<109,x2+y2=z2,gcd(x,y,z)=1。(T≤3,k≤17,1≤ai≤255)。

思路: 考虑预处理, 样例告诉我们所有满足条件的三元组(x, y, z)一共159154994个, 该题时限为4s。 这样的三元组其实就是基本勾股数, 有定理, 对于任意满足一奇一偶, 互质的(m, n)都可以构造出一个对应的基本勾股数(2 * m * n, m * m - n * n, m * m + n * n)。

我们先抛开一奇一偶的限制, 可以用Stern-Brocot tree枚举满足0<nm<1的最简分数。 即初始区间设置为[01,11], 对于区间[ab,cd], 下一个分界点为a+cb+d, 当n∗n+m∗m>109即可退出, 对于那些满足一奇一偶的(m, n), 将max(m * m - n * n, 2 * m * n)纳入贡献中即可。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define ll long long

using namespace std;

const int N = 1 << 17;

int k, cof
, a
;

inline void dfs(int a, int b, int c, int d){
int n = a + c, m = b + d;
if (1LL * n * n + 1LL * m * m > (int)1e9) return;
if ((m - n) % 2) cof[max(m * m - n * n, 2 * n * m) % N] ++;
dfs(a, b, n, m);
dfs(n, m, c, d);
}

int main(){
dfs(0, 1, 1, 1);

int T; scanf("%d", &T);
while (T --){
ll ans = 0;
scanf("%d", &k);
for (int i = 0; i < (1 << k); i ++) scanf("%d", a + i);

for (int i = 0; i < N; i ++)
ans += 1LL * cof[i] * a[i % (1 << k)];

printf("%lld\n", ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: