CF1034A Enlarge GCD

题意翻译

给你n个数,去掉尽量少的数使得剩下数的gcd比原来的大。无解输出-1

Translated by @xzz_233

题目描述

Mr. F has n n n positive integers, a1,a2,…,an a_1, a_2, \ldots, a_n a1​,a2​,…,an​ .

He thinks the greatest common divisor of these integers is too small. So he wants to enlarge it by removing some of the integers.

But this problem is too simple for him, so he does not want to do it by himself. If you help him, he will give you some scores in reward.

Your task is to calculate the minimum number of integers you need to remove so that the greatest common divisor of the remaining integers is bigger than that of all integers.

输入输出格式

输入格式:

The first line contains an integer n n n ( 2≤n≤3⋅105 2 \leq n \leq 3 \cdot 10^5 2≤n≤3⋅105 ) — the number of integers Mr. F has.

The second line contains n n n integers, a1,a2,…,an a_1, a_2, \ldots, a_n a1​,a2​,…,an​ ( 1≤ai≤1.5⋅107 1 \leq a_i \leq 1.5 \cdot 10^7 1≤ai​≤1.5⋅107 ).

输出格式:

Print an integer — the minimum number of integers you need to remove so that the greatest common divisor of the remaining integers is bigger than that of all integers.

You should not remove all of the integers.

If there is no solution, print «-1» (without quotes).

输入输出样例

输入样例#1: 复制

3
1 2 4

输出样例#1: 复制

1

输入样例#2: 复制

4
6 9 15 30

输出样例#2: 复制

2

输入样例#3: 复制

3
1 1 1

输出样例#3: 复制

-1

说明

In the first example, the greatest common divisor is 1 1 1 in the beginning. You can remove 1 1 1 so that the greatest common divisor is enlarged to 2 2 2 . The answer is 1 1 1 .

In the second example, the greatest common divisor is 3 3 3 in the beginning. You can remove 6 6 6 and 9 9 9 so that the greatest common divisor is enlarged to 15 15 15 . There is no solution which removes only one integer. So the answer is 2 2 2 .

In the third example, there is no solution to enlarge the greatest common divisor. So the answer is −1 -1 −1 .


首先求出所有数的gcd,然后每个数都/gcd进行预处理,并统计每个数的个数;

此时我们要做的就是将此时 gcd=1 的序列move 若干个数,使得其 gcd>1

考虑埃筛,我们筛质因数的时候将其倍数的个数也算上,最后 n-cnt 就是需要去掉的数的个数,那么取 min (n-cnt_{i})即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 500005
#define inf 0x3f3f3f3f
#define INF 999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/



ll qpow(ll a, ll b, ll c) {
	ll ans = 1;
	a = a % c;
	while (b) {
		if (b % 2)ans = ans * a%c;
		b /= 2; a = a * a%c;
	}
	return ans;
}

int n;
int a[maxn];
int Map[15000005];
int vis[15000005];

int main()
{
	//ios::sync_with_stdio(0);
	rdint(n);
	for (int i = 1; i <= n; i++)rdint(a[i]);
	int GCD = a[1];
	int Max = -inf;
	for (int i = 2; i <= n; i++)GCD = gcd(a[i], GCD);
	for (int i = 1; i <= n; i++) {
		Map[a[i] / GCD]++; Max = max(Max, a[i] / GCD);
	}
	int ans = 0;
	int tmp = inf;
	for (int i = 2; i <= Max; i++) {
		int res = 0;
		if (!vis[i]) {
			for (int j = i; j <= Max; j += i) {
				vis[j] = 1; res += Map[j];
			}
		}
		tmp = min(tmp, n - res);
	}
	if (tmp == inf)cout << -1 << endl;
	else cout << tmp << endl;
    return 0;
}

.

猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/83894354