Codeforces Round #511 (Div. 2)
https://codeforces.ml/contest/1047/problem/C
C. Enlarge GCD
将数组的每个数除以他们的GCD后,将其每个数分解最小质因数,统计每个数的质其最小因数x的个数,放进一个质因数x集合里,再取出质因数x个数最多的数。
即保留的数最多的数,也就是去除的数最少的答案。
分解最小质因数时,只需筛取1到本数开根号的数即可,1.5e7开根号的质数只有500多个,即最后的复杂度可减枝为o(n*500)。
#include <iostream>
#include <cmath>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
int n,a[300007],tot,prim[1000000],isprim[1000000];
const int N=15000000;
map <int,int> ma;
int gcd(int x,int y){
return y==0? x:gcd(y,x%y);
}
void solve(){
for(int i=0;i<=sqrt(N);i++){
isprim[i]=true;
}
isprim[0]=isprim[1]=0;
for(int i=2;i<=sqrt(N);i++){
if(isprim[i]){
prim[++tot]=i;
for(int j=i*2;j<=sqrt(N);j+=i){
isprim[j]=false;
}
}
}
}
int main(){
solve();
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int gd=a[1];
for(int i=1;i<=n;i++){
gd=gcd(gd,a[i]);
}
for(int i=1;i<=n;i++){
a[i]=a[i]/gd;
}
for(int i=1;i<=n;i++){
int now=0;
for(int j=1;j<=tot;j++){
while(a[i]%prim[j]==0){
//cout<<i<<" "<<prim[j]<<endl;
a[i]/=prim[j];
if(prim[j]==now) continue;
ma[prim[j]]++;
now=prim[j];
}
}
if(a[i]!=1){
ma[a[i]]++;
}
}
int ans=0;
for(auto it:ma){
ans=max(ans,it.second);
}
if(ans!=0) cout<<n-ans<<endl;
else cout<<"-1"<<endl;
}

浙公网安备 33010602011771号