C. Enlarge GCD Codeforces Round #511 (Div. 2)【数学】

题目:

Mr. F has nn 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 nn (2≤n≤3?10^5) — the number of integers Mr. F has.

The second line contains nn integers, a1,a2,…,an (1≤ai≤1.5?10^7).

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

31 2 4

output

1

input

46 9 15 30

output

2

input

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

题意分析:

这题意思就是给你N个数,这N个数会有一个最大公约数G,那么需要去掉K个数,使余下的N-K个数的最大公约数变大。求最小K。

我们从gcd的原理分析,这N个数都除以gcd后,余下的数的最大公约数无法变大时因为不存在公因子,所以我们需要对这N个数进行分类,分类的标准就是是否还有共同的公因子,然后找出包含的数目最多的类别,假设这个类别有M个数。

那么N-M就是我们最终的结果。

这里需要注意的技巧是,在进行类别划分的时候,我们用的素数打表的原理。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 3e5+5;
const int MAX = 1.5e7+5;
int A[MAXN], cnt[MAX];
bool visit[MAX];

int gcd(int a, int b)
{
    return b==0?a:gcd(b, a%b);
}

int Max(const int a, const int b)
{
    return a>b?a:b;
}

int main()
{
    int N;
    while(~scanf("%d", &N))
    {
        int G, ans;
        scanf("%d", &A[0]);
        G = A[0];
        for(int i = 1; i < N; i++)
        {
            scanf("%d", &A[i]);
            G = gcd(G, A[i]);
        }

        memset(cnt, 0, sizeof(cnt));
        memset(visit, true, sizeof(visit));

        for(int i = 0; i < N; i++)
            cnt[A[i]/G]++;

        visit[0] = visit[1] = false;
        ans = 0;
        for(int i = 2; i < MAX; i++)
        {
            int res = cnt[i];
            if(visit[i])
            {
                for(int j = 2*i; j < MAX; j+=i)
                {
                    visit[j] = false;
                    res += cnt[j];
                }
            }
            ans = Max(ans, res);
        }
        printf("%d\n", ans==0?-1:N-ans);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/dybala21/p/9692092.html

时间: 2024-08-30 08:01:03

C. Enlarge GCD Codeforces Round #511 (Div. 2)【数学】的相关文章

Codeforces Round #511 (Div. 2)

又到了摸鱼的时候了23333 A. Little C Loves 3 I 题意:给一个数,分解为不被3整除的3个数 题解:构造,如果这个数被3整除,就构造为1,1,n-2:否则构造为1,2,n-3 1 class Solution(object): 2 def run(self): 3 n = int(input()) 4 if n % 3 == 0: 5 print(1, 1, n - 2) 6 else: 7 print(1, 2, n - 3) 8 9 if __name__ == '__

Codeforces Round #511 (Div. 1)

A - Enlarge GCD 题意:给n个数,那么他们有gcd,去掉最多n-1个数使得他们的gcd变大.求去掉最少的数. 题解:首先如果所有数都相等,那么无解.否则一定有解:最多去掉只剩下最大的那个.gcd是没有影响的,可以直接除掉(注意gcd可以用0来初始化,0和x的gcd都等于x).然后除去gcd之后每个数有他独特的几种因子,把不含这种因子的数都去掉就可以把这种因子释放出来.暴力sqrt分解会T掉,线性筛/埃筛预处理出每个数的最小质因子(甚至不需要预处理出他的幂,反正除一除也是log级别的

Codeforces Round #511 (Div. 2)-C - Enlarge GCD (素数筛)

传送门:http://codeforces.com/contest/1047/problem/C 题意: 给定n个数,问最少要去掉几个数,使得剩下的数gcd 大于原来n个数的gcd值. 思路: 自己一开始想把每个数的因子都找出来,找到这些因子中出现次数最多且因子大于n个数的最大公约数的,(n - 次数 )就是答案.但是复杂度是1e9,差那么一点. 自己还是对素数筛理解的不够深.这道题可以枚举素数x,对于每个x,找到所有(a[i]/gcd(all)) 是x倍数的个数,就是一个次数.找这个次数的过程

Codeforces Round #511 (Div. 2) C. Enlarge GCD (质因数)

题目 题意: 给你n个数a[1]...a[n],可以得到这n个数的最大公约数, 现在要求你在n个数中 尽量少删除数,使得被删之后的数组a的最大公约数比原来的大. 如果要删的数小于n,就输出要删的数的个数, 否则输出 -1 . 思路: 设原来的最大公约数为 g, 然后a[1]...a[n]都除以g ,得到的新的a[1]...a[n],此时它们的最大公约数一定是1 . 设除以g之后的数组a为: 1    2    3     6      8   10  则它们的质因数分别是:  1    2   

Codeforces Round #511 (Div. 2) C. Enlarge GCD

题目链接 题目就是找每个数的最小素因子,然后递归除,本来没啥问题,结果今天又学习了个新坑点. 我交了题后,疯狂CE,我以为爆内存,结果是,我对全局数组赋值, 如果直接赋值,会直接在exe内产生内存,否则只会在运行时才分配内存. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1e7 + 5e6 + 10; 5 6 //线性素数筛 7 int prime[2000000],num_prime = 0;

A. Little C Loves 3 I Codeforces Round #511 (Div. 2) 【数学】

题目: Little C loves number ?3? very much. He loves all things about it. Now he has a positive integer nn. He wants to split nn into 3 positive integers a,b,ca,b,c, such that a+b+c=na+b+c=n and none of the 3 integers is a multiple of 3. Help him to fin

Codeforces Round 511 Div.1 B

Description Given a \(n \times m\) chessboard, every time put two chessman with Manhattan distance 3 between them. Calculate the maximum number of chessmen you can put on it. \(n, m \le 10^9\). Solution All possible pairs of position is a biparite gr

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd