题意:
T组样例,给出 N 个数,求去掉一个数后,数列的最大 GCD。
思路:
维护前缀 GCD 和 后缀GCD 即可。
代码里使用了线段树,其实完全没有必要。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ls l,mid,rt*2
#define rs mid+1,r,rt*2+1
#define sf l,r,rt
#define mi (l+r)/2;
const int MAXN=1e6+100;
int tree[4*MAXN],st,en;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
void push_up(int l,int r,int rt){
tree[rt]=gcd(tree[rt*2],tree[rt*2+1]);
}
void build(int l,int r,int rt){
if(l==r){scanf("%d",&tree[rt]);return ;}
int mid=mi;
build(ls);build(rs);
push_up(sf);
return ;
}
int query(int l,int r,int rt){
if(r<st||l>en) return 0;
if(st<=l&&r<=en) return tree[rt];
int mid=mi;
int ans=query(ls);
if(ans==0) ans=query(rs);
else ans=gcd(ans,query(rs));
return ans;
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
build(1,n,1);
int ans=-1;
for(int i=2;i<n;i++){
st=1;en=i-1;
int temp=query(1,n,1);
st=i+1;en=n;
temp=gcd(temp,query(1,n,1));
ans=max(ans,temp);
}
st=2;en=n;
ans=max(query(1,n,1),ans);
st=1;en=n-1;
ans=max(query(1,n,1),ans);
printf("%d\n",ans);
}
}