Enlarge GCD CodeForces - 1034A(欧拉筛+最大公约数)

题意:

给出n个数,删去其中一些使得总的gcd(最大公约数)最大

题目:

Mr. F has n positive integers, 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.

Input

The first line contains an integer n (2≤n≤3⋅105) — the number of integers Mr. F has.

The second line contains n integers, a1,a2,…,an (1≤ai≤1.5⋅107).

Output

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).

Examples

Input

3
1 2 4

扫描二维码关注公众号,回复: 11317340 查看本文章

Output

1

Input

4
6 9 15 30

Output

2

Input

3
1 1 1

Output

-1

Note

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

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

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

分析:

这道题的思路取自素数筛,甚至是欧拉筛,我们要删除一些数字,
使得gcd增长,那么,我们就得把除去公共gcd之后的数进行一次筛选,
从最小的开始,我们求出那些个有相同质因数的数的数量的最大值。
举个例子: 对于2 4 4 8 8 ; 他们的gcd=2,
除以2以后:1 2 2 4 4,我们从2开始遍历“1~N”,
发现有4个是2的倍数,所以我们删除的是N-4=1。
或许一个例子不够形象: 对于3 6 6 9 ; 它们的gcd=3,
除以3以后:1 2 2 3,我们从2开始,2个是2的倍数, 1个是3的倍数,
之后5、7、11…没有这样的数了,所以删除N-2==2即可。
思路就是这样的。
特殊的,对于除完之后只剩下“1,1,1,1,…”这样的数,我们直接printf("-1\n")。
注意:容易超时,得想办法

AC代码

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int M=1.5e7+5;
const int N=3e5+10;
int sum[M];
int a[N],book[M];
int p[M],tot;
void init()
{
    memset(book,0,sizeof(book));
    for(int i=2; i<M; i++)
    {
        if(!book[i])
            p[tot++]=i;
        for(int j=0; j<tot&&i*p[j]<M; j++)///减少复杂度
        {
            book[i*p[j]]=1;
            if(i%p[j]==0)
                break;
        }
    }
    /**for(int i=2; i<sqrt(M); i++)
    {
        if(!book[i])
            p[tot++]=i;
        for(int j=i*2; j<M; j+=i)
            book[j]=1;
    }*/
}
int main()
{
    int n,x;
    scanf("%d",&n);
    init();
    int d=0;
    for(int i=1; i<=n; i++)//找到所有数的公因数
    {
        scanf("%d",&a[i]);
        d=__gcd(a[i],d);
    }
    for(int i=1; i<=n; i++)
    {
        x=a[i]/d;///把所有的数都除以它们的gcd,则问题变为:保留最多的数,使得它们的gcd不等于1。
        for(int j=0; p[j]*p[j]<=x&&j<tot; j++)///枚举gcd的时候可以只枚举质数。可以通过线性筛将所有的质数O(n)时间复杂度筛出来
        {//除去公因数数之后将所有的数分解
            if(x%p[j]==0)
                sum[p[j]]++;//对素因数计数
            while(x%p[j]==0)
                x/=p[j];
        }
        if(x>1)
            sum[x]++;
    }
    int ans=0;
    for(int i=0; i<tot; i++)
        ans=max(sum[p[i]],ans);//找到最大的素因数出现次数
    if(ans==0)///假设所有数都等于1,显然无解。
        printf("-1\n");
    else
        printf("%d\n",n-ans);
}

猜你喜欢

转载自blog.csdn.net/zeng_jun_yv/article/details/106129712