zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:平方数(数学+哈希)

    题目传送门(内部题137)


    输入格式

      第一行,一个正整数$n$。
      第二行$n$个正整数$a_1sim a_n$。


    输出格式

      输出一个整数,为满足条件的二元组个数。


    样例

    样例输入:

    5
    1 2 3 4 12

    样例输出:

    2


    数据范围与提示

      对于$20\%$的数据,满足$nleqslant 3,000$。
      对于$50\%$的数据,满足$nleqslant 50,000$。
      对于另$20\%$的数据,满足$a_ileqslant 1,000$。
      对于$100\%$的数据,满足$1leqslant nleqslant 300,000,1leqslant a_ileqslant 10^9$。


    题解

    两个数相乘为平方数即其在分解质因数后奇数次的数相同。

    这个可以用哈希维护,用$unordered ext{_}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++

  • 相关阅读:
    Java设计模式--命令模式
    linux 挂载windows盘
    C# 对含有向量偏移的明文进行AES加解密
    Vue修仙之旅之Vue初尝
    Cookie的Secure属性
    Webserver信息泄露的解决方案--使用StripHeaders模块删除不必要的header
    window自定义事件
    vue typescript .eslintrc.js
    css word-break: break-word;无效
    vscode vue 片段
  • 原文地址:https://www.cnblogs.com/wzc521/p/11830142.html
Copyright © 2011-2022 走看看