题意:给出n个数字,求最少删除几个可以使剩下的数字的GCD大于n个数字的GCD。
思路:求出最多的公共因子,去掉没有这个因子的数,剩下的数的GCD大于原来的GCD。
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
#define clr(s, x) memset(s, x, sizeof(s))
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
inline int read(){int r=0;char c=getchar();while(c<'0'||c>'9') {c=getchar();}while(c>='0'&&c<='9') {r=r*10+c-'0';c=getchar();}return r;}
inline ll readll(){ll r=0;char c=getchar();while(c<'0'||c>'9') {c=getchar();}while(c>='0'&&c<='9') {r=r*10+c-'0';c=getchar();}return r;}
inline ll qpow(ll a,ll b,ll mod){ll res=1;while(b){if(b&1)res = (res*a)%mod;a=(a*a)%mod;b>>=1;}return res;}
inline ll gcd(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const double eps = 1e-8;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const int MAXN = 1.5e7+5;
const int MAXM = 1.5e7+5;
int Mark[MAXN];
int prime[MAXN];
int Prime(){
int tot = 0;
memset(Mark, 0, sizeof(Mark));
Mark[0] = 1; Mark[1] = 1;
for(int i = 2; i < MAXN; i++)
{
if(Mark[i] == 0){
prime[tot++] = i;
}
for(int j = 0; j < tot && prime[j] * i < MAXN; j++)
{
Mark[i * prime[j]] = 1;
if(i % prime[j] == 0){
break;
}
}
}
return tot;
}
int a[300005], cnt[MAXN];
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
int tot = Prime();
int n;
scanf("%d", &n);
int g = 0;
for(int i=0; i<n; ++i){
scanf("%d", &a[i]);
g = __gcd(g, a[i]);
}
for(int i=0; i<n; ++i){
a[i] /= g;
for(int j=0; prime[j]*prime[j] <= a[i]; ++j){
int p = prime[j];
if(a[i]%p == 0) cnt[p]++;
while(a[i]%p == 0) a[i] /= p;
}
if(a[i] != 1) cnt[a[i]]++;
}
// puts("*");
int ans = n;
for(int i=2; i<MAXN; ++i){
// printf("%d\n", cnt[i]);
ans = min(ans, n-cnt[i]);
}
if(ans == n) ans = -1;
printf("%d\n", ans);
return 0;
}