CF1034A Enlarge GCD

原题链接

  • 题意:给出 \(n \leqslant 3e5\)\(a_i \leqslant 1.5e7\),要求出来删除最少的数使得所有数的最小公倍数增加。
  • 题解:其实已经很接近想法了,只不过空间存不下。想的是,应该是把所有数除以最小公倍数,然后当前最小公倍数是 \(1\),然后要求最少删除几个数让最小公倍数不是 \(1\) 所以就很简单了。
  • 代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <unordered_map>
#include <cstring>
using namespace std;
typedef long long ll;
const ll N = 2e7 + 9;
const ll mod = 998244353;
int a[N];
int cnt[N];
int pr[N];
bool vis[N];
int pr_cnt;
void get_pr() {
    for (int i = 2; i < N; i ++) {
        if (!vis[i])pr[++pr_cnt] = i;
        for (int j = 1; j <= pr_cnt && i * pr[j] < N; j ++) {
            vis[pr[j] * i] = 1;
            if (i % pr[j] == 0) break;
        }
    }
}
void solve() {
    int n;//cin >> n;

    scanf("%d", &n);
    int GCD = -1;
    for (int i = 1; i <= n; i ++) {
        //cin >> a[i];
        scanf("%d", &a[i]);
        if (GCD == -1) {
            GCD = a[i];
        } else GCD = __gcd(GCD, a[i]);
    }
    int cnt_1 = 0;
    //cout << GCD << endl;
    for (int i = 1; i <= n;i ++) {
        a[i] /= GCD;
        if (a[i] == 1) {cnt_1++;continue;}
        if (!vis[a[i]]) {
            cnt[a[i]]++;
            continue;
        }
        int now = a[i];
        for (int j = 1; pr[j] * pr[j] <= now; j++) {
            if (now % pr[j] == 0 ) {
                while (now %pr[j] == 0)now /= pr[j];
                cnt[pr[j]]++;
            }
        }
        if (now != 1)
        cnt[now] ++;
    }
    int ans = n;
    for (int i = 2; i < N; i ++) {
        ans = min(ans, n - cnt[i]);
    }
    if (ans == n)printf("%d\n", -1);
    else printf("%d\n", ans);

}
signed main() {
    ll t= 1;
    get_pr();
    while (t--) {
        solve();
    }
}
posted @ 2021-05-17 21:12  u_yan  阅读(53)  评论(0)    收藏  举报