Codeforces Round #511 (Div. 2) C. Enlarge GCD (质因数)

Posted thunder-110

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #511 (Div. 2) C. Enlarge GCD (质因数)相关的知识,希望对你有一定的参考价值。

 

题目

 

题意:

  给你n个数a[1]...a[n],可以得到这n个数的最大公约数, 现在要求你在n个数中 尽量少删除数,使得被删之后的数组a的最大公约数比原来的大。 如果要删的数小于n,就输出要删的数的个数, 否则输出 -1 。

 

思路:

  设原来的最大公约数为 g, 然后a[1]...a[n]都除以g ,得到的新的a[1]...a[n],此时它们的最大公约数一定是1 。

  设除以g之后的数组a为: 

              1    2    3     6      8   10

   则它们的质因数分别是:  1    2    3    2 3    2    2 5

  其中 质因数 2 的次数出现的最多,出现了4 次, 所以我们只要删除 n-4=2 个数就能使最大公约数由1 变成 2 。即删除 a[1]和a[3]就好,答案就是 2 。

  综上,只要找出质因数出现的最多的次数d, n-d就是我们要的答案。

 

  代码实现过程中,由于数据较大,要把筛质数 和 选因子  分开来做, 不能同时筛质因子(会超时),因为要避免筛质数这部分重复(打一次表就好)。  筛质数的时候,用2000以内的质数就够了(我也不知道为什么!)

  顺便一提:一个数m 的因子个数k 是小于log2m的 , 因为2^k<m 。 还有 数组至少能开1.5e7 大 。

 

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include <cctype>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<string>
 8 #include<cmath>
 9 #include<set>
10 #include<vector>
11 #include<stack>
12 #include<queue>
13 #include<map>
14 using namespace std;
15 #define ll long long
16 #define mem(a,x) memset(a,x,sizeof(a))
17 #define se second
18 #define fi first
19 const ll mod=1e9+7;
20 const int INF= 0x3f3f3f3f;
21 const int N=3e5+5;
22 
23 
24 const int N2=1.5e7+5;
25 int n;
26 int cnt=0;
27 int check[2005];
28 int a[N];
29 int num[N2];
30 int prime[N];
31 
32 
33 int gcd(int x, int y)
34 {
35     return y==0?x:gcd(y,x%y);
36 }
37 void _prime()
38 {
39     int m=2000;
40     for(int i=2;i<=m;i++) //N以内的质数 
41     {
42         if(!check[i])
43         {
44             prime[++cnt]=i;
45             for(int j=i;j<=m;j+=i)
46             {
47                 check[j]=1;
48             }
49         }
50     }
51 }
52 void factor(int m)
53 {
54     for(int i=1;i<=cnt;i++)
55     {
56         if(m%prime[i]==0)
57             num[prime[i] ]++;
58         while(m%prime[i]==0)
59         {
60             m/=prime[i];
61         }
62     }
63     if(m!=1) //包括了1 
64         num[m]++;
65 }
66 
67 int main()
68 {
69     cin>>n;
70     for(int i=1;i<=n;i++)
71         scanf("%d",&a[i]);
72     
73     int g=a[1]; //g=删除前的最大公约数 
74     for(int i=2;i<=n;i++)    g=gcd(g,a[i]);
75     
76     _prime();
77     for(int i=1;i<=n;i++) 
78     {
79         a[i]/=g;
80         factor(a[i]);
81     }
82     
83     int ans=INF;
84     for(int i=1;i<=N2;i++)
85     {
86         if(num[i])
87             ans=min(ans,n-num[i]);
88     }
89     cout<< (ans<n? ans:-1 )<<endl;
90 }
View Code

 


以上是关于Codeforces Round #511 (Div. 2) C. Enlarge GCD (质因数)的主要内容,如果未能解决你的问题,请参考以下文章

C. Enlarge GCD Codeforces Round #511 (Div. 2)数学

B. Cover Points Codeforces Round #511 (Div. 2)数学

2018.9.21 Codeforces Round #511

Codeforces Round #511 (Div. 1)

Codeforces Round #511 Div2 C. Enlarge GCD

Codeforces Round #511 (Div. 2) C. Enlarge GCD