Coprime Sequence(前后缀GCD)

Description

Do you know what is called ``Coprime Sequence''? That is a sequence consists of $n$ positive integers, and the GCD (Greatest Common Divisor) of them is equal to 1. 
``Coprime Sequence'' is easy to find because of its restriction. But we can try to maximize the GCD of these integers by removing exactly one integer. Now given a sequence, please maximize the GCD of its elements.
 

Input

The first line of the input contains an integer $T(1\leq T\leq10)$, denoting the number of test cases. 
In each test case, there is an integer $n(3\leq n\leq 100000)$ in the first line, denoting the number of integers in the sequence. 
Then the following line consists of $n$ integers $a_1,a_2,...,a_n(1\leq a_i\leq 10^9)$, denoting the elements in the sequence.
 

Output

For each test case, print a single line containing a single integer, denoting the maximum GCD.
 

Sample Input

3
3
1 1 1
5
2 2 2 3 2
4
1 2 4 8
 

Sample Output

1
2
2
 
 
 
 
 
题目意思:给出n个数,去掉其中的一个数,得到一组数,使其最大公约数最大。第一组样例,去掉一个1,得到最大的最大公约数是1。第二组样例,去掉3,得到最大的最大公约数为2。第三组样例,去掉1,得到的最大的最大公约数是2。
 
解题思路:这里使用了之前我没有用到过的一种方法。依次遍历每个数,算出这个数左边的一堆数的最大公约数x1,再算出这个数右边的一堆数的最大公约数x2,gcd(x1,x2)即为删去当前数后剩下的数的最大公约数。遍历每个数得到的最大gcd即为所求。而每个数左边的gcd和右边的gcd可以用O(n)的时间复杂度预处理,遍历每个数是跟前面并列的O(n)复杂度,故可线性解决。
 
 1 #include<stdio.h>
 2 #include<algorithm>
 3 using namespace std;
 4 int gcd(int a,int b) ///基础 辗转
 5 {
 6     int r;
 7     while(b>0)
 8     {
 9          r=a%b;
10          a=b;
11          b=r;
12     }
13     return a;
14 }
15 int a[100005],b[100005],c[100005];
16 int main()
17 {
18     int t,n,i,ans;
19     scanf("%d",&t);
20     while(t--)
21     {
22         scanf("%d",&n);
23         for(i=0;i<n;i++)
24         {
25             scanf("%d",&a[i]);
26         }
27         sort(a,a+n);
28         b[0]=a[0];
29         c[n-1]=a[n-1];
30         for(i=1;i<n;i++)///求前缀GCD
31         {
32             b[i]=gcd(b[i-1],a[i]);
33         }
34         for(i=n-2;i>=0;i--)///求后缀GCD
35         {
36             c[i]=gcd(c[i+1],a[i]);
37         }
38         ans=max(c[1],b[n-2]);
39         for(i=1;i<n-1;i++)
40         {
41             ans=max(ans,gcd(b[i-1],c[i+1]));
42         }
43         printf("%d\n",ans);
44 
45     }
46     return 0;
47 }

 

 

 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2018-05-14 17:53  王陸  阅读(232)  评论(0编辑  收藏  举报