CF1034A Enlarge GCD 题解

题意简述:

删去最少的数使所有的数的 gcd 增加。

解:

先对每个数除以所有数的 gcd,然后剩下的需要找到所有数的质因子,找到一个最多的序列中数拥有的质因子,那么答案就是总数减去拥有这个质因子的数的个数。

用质数筛先预处理,再进行质因子分解,最后取最值即可。

1 就判断所有数是否都为 1 就行。

时间复杂度:O(max(ai))

#include<iostream>
#include<cstdio>
#include<map>
#include<ctime>
using namespace std;
const int N=3e5+5;
const int M=15e6+5;
map<int,int>mp;
int n,ans=1e9,a[N],vis[M],num[M],cnt,pri[M];
int gcd(int x,int y)
{
	if(y==0)return x;
	return gcd(y,x%y);
}
int main()
{
	//freopen("gcd.in","r",stdin);
	//freopen("gcd.out","w",stdout);
	scanf("%d",&n);
	for(int i=2;i<=M-5;i++)
	{
		if(!pri[i])num[++cnt]=i;
		for(int j=1;j<=cnt&&num[j]*i<=M-5;j++)
		{
			pri[num[j]*i]=1;
			if(i%num[j]==0)break; 
		}
	}
	int res=0;
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),res=gcd(res,a[i]);
	for(int i=1;i<=n;i++)
	{
		int x=a[i]/res;
		for(int j=1;num[j]*num[j]<=x;j++)
		{
			if(x%num[j]==0)
			{
				vis[num[j]]++;
				while(x%num[j]==0)x/=num[j];
			}
		}
		if(x!=1)vis[x]++;
	}
	for(int i=1;i<=M-5;i++)if(vis[i]&&vis[i]!=n)ans=min(ans,n-vis[i]);
	if(ans>n)printf("-1");
	else printf("%d",ans);
	return 0;
}
posted @   Gmt丶Fu9ture  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示