zoukankan      html  css  js  c++  java
  • AtCoderAGC003D Anticube

    Description:

    给定一个序列(a),要求选出最多的序列元素并保证两两元素的乘积不为立方数

    Solution:

    我们考虑哪些因子是有用的,如果一个因子的指数(>3),我们可以将他化简为( ext{%3})后的指数,这样不影响他找对应的不能一起选的,那我们先将所有数化简并分类(map一下),找出他们的补数(不能一起选的数),然后贪心的选择最大的,这一步需要质因数分解,但是(10^{10})太大了,其实我们只用分解(10^{frac{10}{3}}),剩下的因子只有几种情况,<1>只剩一个因子,<2>剩下两个因子,可能是完全平方数也可能不是,这些情况我们均可确定简数以及补数。注意:如果一个数与他的补数相等,我们只能选一个
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<map>
    using namespace std;
    const int MAXX=3000;
    const int MAXN=100010;
    map<long long ,int >num;
    map<long long ,bool >vis;
    int prime[MAXN],v[MAXN];
    int n,tot,ans;
    long long a[MAXN],b[MAXN];
    inline void init(){
        for(int i=2;i<=MAXX;++i){
        	if(!v[i]){
        		prime[++tot]=i;
        		v[i]=i;
        	}
        	for(int j=1;j<=tot;++j){
        		if(i*prime[j]>MAXX||v[i]<prime[j])break;
        		v[i*prime[j]]=prime[j];
        	}
        }
    }
    inline void solve(long long x,int pos){
    	long long u=1;
    	long long v=1;
        for(int i=1;i<=tot;++i){
        	if(x%prime[i]==0){
            long long cnt=0;
            while(x%prime[i]==0){
               x/=prime[i];
               cnt++;
             }
              cnt%=3;
              if(cnt==1){
              	u*=prime[i];
              	v*=prime[i]*prime[i];
              }
              if(cnt==2){
              	u*=prime[i]*prime[i];
              	v*=prime[i];
              }
           }
           if(x==1)break;
        }
        if(x>1){
        	long long t=(long long)sqrt(x);
        	u*=x;
        	if((t*t)==x)v*=t;
        	else v*=x*x;
        }
        a[pos]=u;
        b[pos]=v;
        num[u]++;
    }
    int main(){
        init();
        scanf("%d",&n);
        for(int i=1;i<=n;++i)cin>>a[i];
        for(int i=1;i<=n;++i)solve(a[i],i);
        for(int i=1;i<=n;++i){
        	if(!vis[a[i]]){
        		vis[a[i]]=1;
        		vis[b[i]]=1;
        		if(a[i]==b[i])ans++;
        		else ans+=max(num[a[i]],num[b[i]]);
        	}
        }
        cout<<ans<<endl;	
        return 0;
    }
    
  • 相关阅读:
    Linux上Nginx部署配置--二级域名配置
    Android-Gallery GridView ImageSwitcher 使用
    Android:控件布局(相对布局)RelativeLayout(转)
    Win10 安装msi 提示2502、2503的错误代码 -- 命令提示符(管理员) -- msiexec /package
    storm 入门原理介绍_AboutYUN
    storm入门教程 第一章 前言
    Hbase存储详解
    浅谈设计模式
    Hadoop分布式文件系统--HDFS结构分析
    YARN源码分析(一)-----ApplicationMaster
  • 原文地址:https://www.cnblogs.com/ARTlover/p/9582275.html
Copyright © 2011-2022 走看看