Coprime Sequence (前缀后缀GCD问题)

Description

Do you know what is called ``Coprime Sequence''? That is a sequence consists of nn 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(1T10)T(1≤T≤10), denoting the number of test cases. 
In each test case, there is an integer n(3n100000)n(3≤n≤100000) in the first line, denoting the number of integers in the sequence. 
Then the following line consists of nn integers a1,a2,...,an(1ai109)a1,a2,...,an(1≤ai≤109), 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

题意:

给出一系列数,它们的最大公约数为1 ,现在你需要在这些数中删掉任意一个数使剩下的书的最大公约数最大

思路:

依次遍历每个数,算出这个数左边的一堆数的最大公约数x1,再算出这个数右边的一堆数的最大公约数x2,gcd(x1,x2)即为删去当前数后剩下的数的最大公约数。遍历每个数得到的最大gcd即为所求。

而每个数左边的gcd和右边的gcd可以用O(n)的时间复杂度预处理,遍历每个数是跟前面并列的O(n)复杂度,故可线性解决。

代码如下:

  1. #include <bits/stdc++.h>  
  2. using namespace std;  
  3. #define mst(a,b) memset((a),(b),sizeof(a))  
  4. #define f(i,a,b) for(int i=(a);i<=(b);++i)  
  5. #define ll long long  
  6. const int maxn = 100005;  
  7. const int mod = 1e9+7;  
  8. const int INF = 0x3f3f3f3f;  
  9. const double eps = 1e-6;  
  10. #define rush() int T;scanf("%d",&T);while(T--)  
  11. int gcd(int a,int b)  
  12. {  
  13.     return b?gcd(b,a%b):a;  
  14. }  
  15. int a[maxn];  
  16. int l[maxn];  
  17. int r[maxn];  
  18. int main()  
  19. {  
  20.     int n;  
  21.     rush()  
  22.     {  
  23.         scanf("%d",&n);  
  24.         for(int i=0;i<n;i++)  
  25.         {  
  26.             scanf("%d",&a[i]);  
  27.         }  
  28.         l[0]=a[0];  
  29.         r[n-1]=a[n-1];  
  30.         for(int i=1;i<n;i++)         //求前缀GCD      
  31.         {  
  32.             l[i]=gcd(l[i-1],a[i]);  
  33.         }  
  34.         for(int i=n-2;i>=0;i--)      //求后缀GCD  
  35.         {  
  36.             r[i]=gcd(r[i+1],a[i]);  
  37.         }  
  38.         int ans=max(l[n-2],r[1]);  
  39.         for(int i=1;i<n-1;i++)       //遍历求最大值  
  40.         {  
  41.             ans=max(ans,gcd(l[i-1],r[i+1]));  
  42.         }  
  43.         printf("%d\n",ans);  
  44.     }  
  45.     return 0;  
  46. }  
代码引用:https://blog.csdn.net/my_sunshine26/article/details/71320170

猜你喜欢

转载自blog.csdn.net/Baiyi_destroyer/article/details/80170895