码迷,mamicode.com
首页 > 其他好文 > 详细

[CSP-S模拟测试]:平方数(数学+哈希)

时间:2019-11-10 15:33:58      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:比较   int   space   输入   元组   代码   正整数   its   sharp   

题目传送门(内部题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++

[CSP-S模拟测试]:平方数(数学+哈希)

标签:比较   int   space   输入   元组   代码   正整数   its   sharp   

原文地址:https://www.cnblogs.com/wzc521/p/11830142.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!