Codeforces Round #511 Div2 C. Enlarge GCD

Posted hfccccccccccccc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #511 Div2 C. Enlarge GCD相关的知识,希望对你有一定的参考价值。

http://codeforces.com/contest/1047/problem/C

问题

给一个序列 (A),计原序列所有数的最大公约数为 (p)。现在要删除一些数形成一个新序列,计新序列所有数的最大公约数为 (q) 问最少删除多少数能使 (q > p)

题解

先求出 (p),然后枚举 (q > p),计算一下序列中 (q) 的倍数有哪些。注意到若存在 (a | q)(a > p),那么 (a) 显然优于 (p),因此用一个类似筛法的方法枚举就好了,复杂度 (O(N cdot log{log{N}}))

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int rint() {
    int n, c, sgn = 0;
    while ((c = getchar()) < ‘-‘);
    if (c == ‘-‘) n = 0, sgn = 1;
    else n = c - ‘0‘;
    while ((c = getchar()) >= ‘0‘) {
        n = 10 * n + c - ‘0‘;
    }
    return sgn ? -n : n;
}

const int N = 300010;
const int MAX = 1.5e7 + 10;

int n;
bool mark[MAX];
int cnt[MAX];

int main() {
    scanf("%d", &n);
    int g = 0;
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        cnt[x]++;
        g = __gcd(g, x);
    }

    int ans = n;
    for (int d = g + 1; d < MAX; d++) {
        if (mark[d]) continue;
        int need = 0;
        for (ll j = d; j < MAX; j += d) {
            mark[j] = true;
            need += cnt[j];
        }
        if (need > 0) {
            ans = min(ans, n - need);
        }
    }
    if (ans == n) puts("-1");
    else printf("%d
", ans);

    fprintf(stderr, "%.3lf sec
", double(clock()) / CLOCKS_PER_SEC);
    return 0;
}

以上是关于Codeforces Round #511 Div2 C. Enlarge GCD的主要内容,如果未能解决你的问题,请参考以下文章

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

B. Cover Points Codeforces Round #511 (Div. 2)数学

Codeforces Round #511 (Div. 1)

Codeforces Round #511 Div2 C. Enlarge GCD

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

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