Description
In mathematics, a square number is an integer that is the square of an integer. In other words, it is the product of some integer with itself. For example, 9 is a square number, since it can be written as 3 * 3.
Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a square number.
Input
The first line of the input contains an integer T (1 ≤ T ≤ 20) which means the number of test cases.
Then T lines follow, each line starts with a number N (1 ≤ N ≤ 100000), then N integers followed (all the integers are between 1 and 1000000).
Output
For each test case, you should output the answer of each case.
Sample Input
1 5 1 2 3 4 12
Sample Output
2 /*题意*/一个整数,可以被表示为另一个整数的平方,这个整数称为平方数。
给你一个序列ai ~aj,规模为1e5,让你找出有多少对(ai,aj),使得ai×aj为平方数。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 1e6 + 10;
int isprime[maxn];
int prime[maxn];
int num[maxn];
int factor[maxn]; //该数组是将质因数分解后保存的某个因数的个数
int k = 0;
void init() //素数打表
{
isprime[0] = 1;
isprime[1] = 1;
for(int i = 2; i < maxn; i++){
if(!isprime[i]){
prime[k++] = i;
for(int j = 2*i; j < maxn; j += i){
isprime[j] = 1;
}
}
}
}
int main()
{
init(); //素数打表
int t;
scanf("%d", &t);
while(t--){
memset(factor, 0, sizeof(factor));
int n;
scanf("%d", &n);
long long ans = 0;
for(int i = 0; i < n; i++)
scanf("%d", &num[i]);
for(int i = 0; i < n; i++){
int temp = num[i];
int remain = 1;
for(int j = 0; j < k; j++){ //这里是不会超时的虽然k有可能很大但是接近1e6的值的个数n在10^2 ~ 10^3左右个自己可以手动算一下范围
int times = 0;
while(temp % prime[j] == 0){
temp /= prime[j];
times++;
}
if(times & 1){ //按位与对应二进制位都为1时当前位为1
remain *= prime[j]; //这里是保存上一个状态与当前的值(如:30 = 2 * 3 * 5)自己推一下看看必须是 *=
}
if(!isprime[temp] || temp == 1){
remain *= temp;
break;
}
}
//ans += factor[remain]++;//可以合到一起但是如果该题试求立方和数下面两步就需要很清楚(见下一篇博客立方和数)
ans += factor[remain]; //这一步是若出现一个remain可匹配数那么就有一个平方数
factor[remain]++; //这里是将出现过的需要匹配的数加加
}
printf("%lld\n", ans);
}
return 0;
}