题目描述
给NN个正整数, 第ii个数用aiai来表示, 求出有多少对(i,j)(i,j) 使得a2i+ajai2+aj是一个完全平方数.
输入格式
第一行一个正整数nn 第二行nn个数, 表示a1,a2,a3...ana1,a2,a3...an.
输出格式
一行一个整数, 表示答案
数据范围
对于所有测试数据 满足1≤n≤106, 且1≤ai≤106
样例输入
5
1 2 3 4 5
样例输出
2
解决:
对于一个长度为1e6的数组,询问a[i] ^2 - a[j] 为一个平方数的方案数是多少。
也就是x ^ 2 + y = z ^ 2的个数,移项得,y = (z - x) (z + x)
其中,z可以是任意得数,而y和x都是原数组中的元素,我们可以通过枚举y的所有因子,并判断是否存在x来判断当前x和y是否合法
若y = a * b , 如果合法,x = (b - a) / 2
为了能够降低时间复杂度,我们枚举因子i,然后枚举因子i的倍数作为y。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int n;
int a[N], cnt[N];
void work()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
{
scanf("%d", &a[i]);
cnt[a[i]] ++;
}
long long ans = 0;
for (int i = 1; i <= N - 10; i ++ )
for (int j = i; j <= N - 10; j += i)
{
int mx = max(i, j / i), mi = min(i, j / i);
if ((mx - mi) % 2 == 0)
{
ans += (long long)cnt[j] * cnt[(mx - mi) / 2];
}
}
cout << ans / 2 << endl;
}
int main(){
work();
}