題面:給定長為n的陣列A,問有多少對下標(i,j)滿足A[i]*A[j]為完全平方數?
範圍:n<=2E5; A[i]<=2E5
思路:完全平方數即質因子的個數為偶數,因此對元素進行化簡,把偶次質因子都去掉,再統計即可。另外,0乘任何數都為0,需要單獨處理。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)
map<int,int> factor(int z) {
map<int,int> p;
for (int i = 2; i <= z/i; i++) {
while (z % i == 0) {
p[i] += 1;
z /= i;
}
}
if (z > 1) p[z] += 1;
return p;
}
void solve() {
int n;
cin >> n;
int ans = 0, cnt0 = 0;
map<int,int> cnt;
rep(i,1,n) {
int A;
cin >> A;
if (A == 0) {
ans += i-1;
cnt0 += 1;
continue;
}
int a = 1;
for (auto [k,v] : factor(A)) {
if (v % 2) a *= k;
}
ans += cnt[a] + cnt0;
cnt[a] += 1;
}
cout << ans << "\n";
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}