题解:由于注意到x的范围较小,我们显然可以同时枚举x与p进行计算。先枚举想,在枚举p的过程中,我们发现,对于同一个x,不同的p可能会算出同一个y,导致重复。为了解决这种状况,我们可以先求出所有数的所有因数,在那之后,我们对于同一个x,用一个vis数组记录所有产生的y,并在记录时计数即可。
PS:技巧:我们可以在每次记录y是,vis数组的标记用当前的x,而不是1,这样判断时只需要比较是否为当前的x即可,省去了对于不同的x,vis数组进行初始化的时间
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 800000 + 10;
vector<int> G[maxn];
int m,vis[maxn];
int main()
{
for(int i = 1;i < maxn;i++){
for(int j = i;j < maxn;j+=i){
G[j].push_back(i);
}
}
int kase;scanf("%d",&kase);
while(kase--){
scanf("%d",&m);
memset(vis,0,sizeof(vis));
int ans = 0;
for(int i = 1;i * i < m;i++){
for(int p = 1;p * i * i < m;p++){
int tmp = m - p * i * i;
for(int j = 0;j < G[tmp].size();j++){
if(vis[G[tmp][j]] != i){
vis[G[tmp][j]] = i;
ans++;
}
}
}
}
printf("%d\n",ans);
}
return 0;
}