有 \(T\) 组询问,每次给出 \(n\) 个数 \(a_i\)。
你需要找到这个数组的一个子序列(要求编号连续),使得该序列中所有数的最大公约数和序列长度的乘积最大,并输出这个最大值
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+5;
int n,a[N],st[N][21],logN[N];
inline int getgcd(int l,int r){
int s=logN[r-l+1];
return __gcd(st[l][s],st[r-(1<<s)+1][s]);
}
signed main(){
int T; cin>>T;
while(T--){
scanf("%lld",&n);
logN[0]=-1;
int sum=0;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
st[i][0]=a[i];
logN[i]=logN[i>>1]+1;
sum=max(sum,a[i]);
}
for(int j=1;j<=logN[n];j++)
for(int i=1;i+(1<<j)-1<=n;i++)
st[i][j]=__gcd(st[i][j-1],st[i+(1<<(j-1))][j-1]);
for(int i=1;i<=n;i++){
int l,r,res=a[i],mid,lst=i;
while(1){
l=lst,r=n;
while(l<=r){
mid=(l+r)>>1;
if(res==getgcd(i,mid))l=mid+1;
else r=mid-1;
}
sum=max(sum,(l-i)*res);
if(l==n+1)break;
lst=l;
res=getgcd(i,l);
}
}
printf("%lld\n",sum);
}
}