zoukankan      html  css  js  c++  java
  • Codeforces1325E Ehab's REAL Number Theory Problem

    Description

    link

    给一些数字,问最少取多少个数字,使得它们的乘积为完全平方数?

    求最少取几个

    每个数字满足因数个数不超过7个

    $n leq 10^5 $ (a_i leq 10^6)

    Solution

    这个题是一个在值域上面做文章的题目

    性质挺美好的吧

    首先对于每个数字进行判断,如果直接是,就输出掉

    然后把每个数中的完全平方因子卡掉

    之后!!我们发现质因子个数小于3个!!!

    因为(2 imes 2 imes 2= 8)

    然后就是一个找最小环呗

    如果一个质因子,就跟 (1) 建边,否则两个质因子互相建边

    这里需要质数的离散化

    (博主比赛的时候发现了这个题,但是不会找最小环)

    (Bfs)一下吧,具体直接见代码

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=2e6+10,inf=0x3f3f3f3f3f3f3f3f;
    	int num,pri[N],ans,pos[N],dis[N],n,R;
    	bool fl[N];
    	inline void prework()
    	{
    		fl[1]=1; pos[1]=R=1;
    		for(int i=2;i<N;++i) 
    		{			
    			if(!fl[i])
    			{
    				pri[++num]=i; pos[i]=num+1;
    				if(i<1000) ++R;
    			}
    			for(int j=1;j<=num&&i*pri[j]<N;++j) 
    			{
    				fl[pri[j]*i]=1; if(i%pri[j]==0) break;
    			}
    		}return ;
    	}
    	int cnt,head[N];
    	struct node{int to,nxt;}e[N<<1];
    	inline void add(int u,int v)
    	{
    		e[++cnt].nxt=head[u]; e[cnt].to=v;
    		return head[u]=cnt,void();
    	}
    	inline void build(int x)
    	{
    		int tot=0,a[10]={0};
    		for(int i=2;i*i<=x;++i)
    		{
    			if(x%i==0)
    			{
    				int cnt=0;
    				while(x%i==0) ++cnt,x/=i;
    				if(cnt&1) a[++tot]=i; 
    			}
    		}
    		if(x>1) a[++tot]=x;
    		if(!a[1]&&!a[2]) puts("1"),exit(0);
    		if(!a[2]) add(pos[a[1]],1),add(1,pos[a[1]]);
    		else add(pos[a[1]],pos[a[2]]),add(pos[a[2]],pos[a[1]]); 
    	}
    	signed main()
    	{
    		prework();
    		n=read(); ans=inf;
    		for(int i=1;i<=n;++i) build(read());
    		for(int s=1;s<=R;++s)
    		{
    			memset(dis,0x3f,sizeof(dis)); dis[s]=0;
    			queue<pair<int,int> >q; q.push(make_pair(s,0));
    			while(!q.empty())
    			{
    				int fr=q.front().first,fa=q.front().second; q.pop();
    				for(int i=head[fr];i;i=e[i].nxt)
    				{
    					int t=e[i].to; if(t==fa) continue;
    					if(dis[t]>=inf) dis[t]=dis[fr]+1,q.push(make_pair(t,fr));
    					else if(dis[fr]+dis[t]>0) ans=min(ans,dis[t]+dis[fr]+1);
    				 } 
    			}
    		}
    		if(ans>n) ans=-1;
    		printf("%lld
    ",ans);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    20145240 《信息安全系统设计基础》第0周学习总结
    20145240《Java程序设计》课程总结
    20145240 《Java程序设计》第五次实验报告
    20145240 《Java程序设计》第十周学习总结
    20145240 《Java程序设计》第四次实验报告
    20145240 《Java程序设计》第九周学习总结
    20145240 《Java程序设计》第三次实验报告
    20145240 《Java程序设计》第八周学习总结
    20145240《Java程序设计》第七周学习总结
    20145239 《信息安全系统设计基础》第2周学习总结
  • 原文地址:https://www.cnblogs.com/yspm/p/12550038.html
Copyright © 2011-2022 走看看