Coprime Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2186 Accepted Submission(s): 1022
Problem 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.
``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≤T≤10), denoting the number of test cases.
In each test case, there is an integer n(3≤n≤100000) in the first line, denoting the number of integers in the sequence.
Then the following line consists of n integers a1,a2,...,an(1≤ai≤109), denoting the elements in the sequence.
In each test case, there is an integer n(3≤n≤100000) in the first line, denoting the number of integers in the sequence.
Then the following line consists of n integers 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
题意:给出n个数,可以从中任意删除一个数,使得剩余其他数的gcd和最大
题解:
起初算法:枚举我们我们需要的删除的是哪个,对于其他的需要O(n)的计算其们的GCD
算法的时间复杂度是O(n^2) 而本题的n为1e5,显然不允许我们使用O(n^2)的算法
最终算法:对于每次的遍历需要O(n)的时间,显然我们会重复计算很多次,如果能记录就好了
而我们想到删除其中一个将原数组分成了2半,而我们只要提前记录这两半就好了
于是想到记录前缀GCD和后缀GCD,对于删除第i个数来说,
我们可以很快的计算出其他的GCD = gcd(pre[i-1],suf[i+1])
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6+10;
int arr[maxn],pre[maxn],suf[maxn];
void init(){
memset(pre,0,sizeof(pre));
memset(suf,0,sizeof(suf));
}
int main()
{
int caset;scanf("%d",&caset);
while(caset--)
{
init();
int n;scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&arr[i]);
pre[0] = arr[0];suf[n-1] = arr[n-1];
for(int i=1;i<n;i++) pre[i] = __gcd(pre[i-1],arr[i]);
for(int i=n-2;i>=0;i--) suf[i] = __gcd(suf[i+1],arr[i]);
int ans = -1;
for(int i=0;i<n;i++) {
if(i == 0) ans = max(ans,suf[1]);
else if(i == n-1) ans =max(ans,pre[n-2]);
else ans = max(ans,__gcd(pre[i-1],suf[i+1]));
}
printf("%d\n",ans);
}
return 0;
}