原题链接
- 题意:给出 (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
", -1);
else printf("%d
", ans);
}
signed main() {
ll t= 1;
get_pr();
while (t--) {
solve();
}
}