学哈希表时的习题。
H:a*x1^2+b*x2^2 = -(c*x3^2+d*x4^2),H关于X轴对称,由于会有负下标,我们把函数位置右移maxn,即H(x+maxn) = H(maxn-x),原函数关于X=maxn对称。
所以我们可以先算出X右边的所有数,然后通过左边的数去映射右边的数,把所有可能解相加。因为x1,x2,x3,x4可以为正数或者为负数两种情况,所以在找到一种可能解时,需要把结果乘以2的4次幂。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
#include <stack>
using namespace std;
const int maxn = 1000000;
#define H(i) hash[(i)+maxn]
int hash[maxn*2];
int a, b, c, d;
typedef long long LL;
f(x+a) = f(x-a);
void solve()
{
if((a > 0 && b > 0 && c > 0 && d > 0) ||(a < 0 && b < 0 && c < 0 && d < 0)) { printf("0\n"); return ; }
memset(hash, 0, sizeof(hash));
for(int i = 1; i <= 100; i++)
for(int j = 1; j <= 100; j++) H(a*i*i+b*j*j)++;
int ans = 0;
for(int i = 1; i <= 100; i++)
for(int j = 1; j <= 100; j++)
{
int t = -(c*i*i+d*j*j);
ans += H(t);
}
printf("%d\n", ans*(1<<4));
}
int main()
{
while(~scanf("%d%d%d%d", &a, &b, &c, &d))
{
solve();
}
return 0;
}