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