您现在的位置是:首页 >学无止境 >C. Enlarge GCD(内存的限制 + 数组的访问速度)网站首页学无止境

C. Enlarge GCD(内存的限制 + 数组的访问速度)

WYW___ 2024-06-14 17:17:16
简介C. Enlarge GCD(内存的限制 + 数组的访问速度)

Problem - C - Codeforces

Mr. F 有 n 个正整数 a1,a2,…,an。

他认为这些整数的最大公约数太小了。所以他想通过删除其中一些整数来扩大它。

但是这个问题对他来说太简单了,所以他不想自己做。如果你帮他解决这个问题,他会给你一些奖励分数。

你的任务是计算您需要删除的最少数量的整数,以便剩余整数的最大公约数大于所有整数的最大公约数。

输入 第一行包含一个整数 n (2≤n≤3⋅105) — Mr. F 拥有的整数数量。

第二行包含 n 个整数 a1,a2,…,an (1≤ai≤1.5⋅107)。

输出 请输出一个整数 — 您需要删除的最少数量的整数,以便剩余整数的最大公约数大于所有整数的最大公约数。

您不应该删除所有整数。

如果没有解决方案,请输出 "-1"(不要引号)。

Examples

input

Copy

3
1 2 4

output

Copy

1

input

Copy

4
6 9 15 30

output

Copy

2

input

Copy

3
1 1 1

output

Copy

-1

 

在第一个例子中,最大公约数一开始为1。你可以去掉1,使得最大公约数变成2。答案是1。

在第二个例子中,最大公约数一开始为3。你可以去掉6和9,使得最大公约数变成15。没有只去掉一个整数就能实现的解决方案。因此答案是2。

在第三个例子中,没有办法扩大最大公约数。因此答案是-1。

题解:
对于有很多数据的题目尽量不用map,用数组进行操作,

一般来说,题目给的内存限制,只够我们开到2e7的数组

对于不是太大的输入输出,如果超时,可能时#define int long long的原因

对于本题来说,首先线性筛筛质数,

每个数/数组的最大公约数,记录剩下数中都含有什么因子,

含有的因子最多的便是我们应该保留的数目

注意特判,数组中数全部相等的情况

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define int long long
typedef pair<int,int> PII;
const int N = 1.5e7 + 10;
int mod = 1e9 + 7;
int pri[N/10];
int vis[N];
int a[300050]; 
int c[N];
void solve()
{
	int n;
	scanf("%d",&n);
	int cnt = 0;
	for(int i = 2;i <= N - 10;i ++)
	{
		if(!vis[i])
		{
			pri[++cnt] = i;
		}
		for(int j = 1;j <= cnt&&i*pri[j] <= N;j++)
		{
			vis[i*pri[j]] = 1;
			if(i%pri[j] == 0)
			break;
		}
	}
	int g = 0;
	for(int i = 1;i <= n;i++)
	{
		scanf("%d",&a[i]);
		g = __gcd(a[i],g);
	}
	for(int i = 1;i <= n;i++)
	{
		a[i] /= g;
		for(int j = 1;pri[j]*pri[j] <= a[i];j++)
		{
			if(a[i]%pri[j] == 0)
			{
				c[pri[j]]++;
				while(a[i]%pri[j] == 0)
				{
					a[i] /= pri[j];
				}
			}
		}
		if(a[i] > 1)
		c[a[i]]++;
	}
	int ans = 1e9;
	for(int i = 1;i <= N - 10;i++)
	{
		ans = min(ans,n - c[i]);
	}
	if(ans == n)
	{
		printf("-1");
	}
	else
	{
		printf("%d",ans);
	}
}

signed main()
{
//	ios::sync_with_stdio(0 );
//	cin.tie(0);cout.tie(0);
	int t = 1;
//	cin >> t;
	while(t--)
	{
		solve(); 
	}
}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。