题目传送门(内部题137)
输入格式
第一行,一个正整数$n$。
第二行$n$个正整数$a_1\sim a_n$。
输出格式
输出一个整数,为满足条件的二元组个数。
样例
样例输入:
5
1 2 3 4 12
样例输出:
2
数据范围与提示
对于$20\%$的数据,满足$n\leqslant 3,000$。
对于$50\%$的数据,满足$n\leqslant 50,000$。
对于另$20\%$的数据,满足$a_i\leqslant 1,000$。
对于$100\%$的数据,满足$1\leqslant n\leqslant 300,000,1\leqslant a_i\leqslant 10^9$。
题解
两个数相乘为平方数即其在分解质因数后奇数次的数相同。
这个可以用哈希维护,用$unordered\text{_}map$记录一下就好了。
质数比较多,但是我们可以只利用前几个质数就好了。
时间复杂度:$\Theta(kn)$($k$为利用的质数的个数)。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h> using namespace std; unordered_map<int,int>mp; int n; int pri[170],cnt; bool vis[1000]; long long ans; void pre_work() { for(int i=2;i<1000;i++) { if(vis[i])continue;pri[++cnt]=i; for(int j=i;j<1000;j+=i)vis[j]=1; } } int main() { pre_work(); scanf("%d",&n); while(n--) { int x,res=1; scanf("%d",&x); for(int i=1;i<=cnt;i++) { while(!(x%(pri[i]*pri[i])))x/=pri[i]*pri[i]; if(!(x%pri[i])){x/=pri[i];res*=pri[i];} } if((int)(sqrt(x))*(int)(sqrt(x))!=x)res*=x; ans+=mp[res];mp[res]++; } printf("%lld",ans); return 0; }
rp++
原文地址:https://www.cnblogs.com/wzc521/p/11830142.html
时间: 2024-11-06 03:52:22