Enlarge GCD CodeForces
阿新 • • 發佈:2018-12-12
題目大意: 給你n個數,他們有一個最大公約數,問你刪掉最少幾個數,可以讓他們的最大公約數變大。 分析: 首先想到的是分解者n個數的因子,然後對於2到maxn的數字,選擇一個出現次數最多的因子,n-這個數目就是答案,但是分解因子的複雜度是n*sqrt(a[i]),這樣會超時,所以換一種求因子的方法,對於每一個數,找他的最小質數因子,每次除它,統計因子
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <set> #include <cmath> using namespace std; const int maxn = 1e7+5e6+10; int a[maxn]; int b[maxn],prime[maxn],div1[maxn]; void init() { for(int i=2;i<maxn;i++) { if(!prime[i]) { prime[++prime[0]]=i; div1[i]=i; } for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++) { prime[prime[j]*i]=1; div1[prime[j]*i]=prime[j]; if(i%prime[j]==0) break; } } } //void solve(int x) //{ // for(int i=1;i<=sqrt(x);i++) // { // if(x%i==0) // { // a[i]++; // if(x/i!=i) // a[x/i]++; // } // } //} void solve(int x) { if(x==1||prime[x]==0) { a[x]++; } else { // a[x]++; while(x>1) { int t=div1[x]; //cout<<t<<endl; a[t]++; while(x%t==0&&x!=1) { x/=t; } } } } int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } int main() { init(); int n; scanf("%d",&n); int g;int x; for(int i=0;i<n;i++) { scanf("%d",&b[i]); if(i==0) g=b[i]; else g=gcd(b[i],g); //cout<<g<<endl; //solve(); } for(int i=0;i<n;i++) { solve(b[i]/g); } int ans=maxn; // cout<<g<<endl; for(int i=2;i<maxn;i++) { if(a[i]) ans=min(ans,n-a[i]); //cout<<n-a[i]<<endl; } if(ans==maxn) printf("-1\n"); else printf("%d\n",ans); return 0; }