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
题意:
平方数:某个整数的平方;
给定一串整数(a1,a2........an),求有多少对整数的乘积(ai*aj),使得这个乘积为平方数。
题解:
唯一分解定理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积
那么平方数肯定能分解成若干素数的偶次幂,先将每个质数的平方打表,将分解后剩余的部分存入数组中,最后两两配对。
代码:
#include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <vector> #include <map> #include <set> #include <bitset> #include <queue> #include <deque> #include <stack> #include <iomanip> #include <cstdlib> using namespace std; #define is_lower(c) (c>=‘a‘ && c<=‘z‘) #define is_upper(c) (c>=‘A‘ && c<=‘Z‘) #define is_alpha(c) (is_lower(c) || is_upper(c)) #define is_digit(c) (c>=‘0‘ && c<=‘9‘) #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define IO ios::sync_with_stdio(0);\ cin.tie(0); cout.tie(0); #define For(i,a,b) for(int i = a; i <= b; i++) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef vector<int> vi; const ll inf=0x3f3f3f3f; const double EPS=1e-10; const ll inf_ll=(ll)1e18; const ll mod=1000000007LL; const int maxn=1000000; bool vis[maxn+1000000]; int prime[maxn],prime1[maxn]; bool isprime[maxn+5]; int cnt[maxn+5]; int num = 0; void getprime() { memset(vis, false, sizeof(vis)); int N = sqrt(maxn); for (int i = 2; i <= N; ++i) { if ( !vis[i] ) { prime[++num] = i; prime1[num] = i*i; } for (int j = 1; j <= num && i * prime[j] <= N ; j++) { vis[ i * prime[j] ] = true; if (i % prime[j] == 0) break; } } } int main() { int T; cin>>T; getprime(); while(T--) { int x; memset(cnt,0,sizeof(cnt)); cin>>x; For(i,1,x) { int xx; cin>>xx; for(int j = 1; xx>=prime1[j]&&j<=num; j++) { while(xx%prime1[j]==0) xx/=prime1[j]; } cnt[xx]++; } ll ans = 0; For(i,1,maxn-1) if(cnt[i]) ans+= cnt[i]*(cnt[i]-1)/2; cout<<ans<<endl; } return 0; } /*************************************************** User name: exist Result: Accepted Take time: 572ms Take Memory: 2544KB Submit time: 2018-03-17 13:55:51 ****************************************************/