题解:每加入一个数,将此数作为一个区间,区间值为数的值。把之前所有区间的值与此数做一遍
,更新区间的值,如果相邻区间的值相同,则合并这两个区间。最后扫一遍所有区间求出
。如此做
次即可。由于每次
值至少减少一半,所以区间最多
个。
时间复杂度
。
#include<bits/stdc++.h>
#define N 100005
#define ll long long
using namespace std;
ll a[N],b[N],l[N],r[N],ans;
int main()
{
int cnt=0,n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ans=0;
for(int i=1;i<=n;i++)
{
b[++cnt]=a[i];
l[cnt]=i;
r[cnt]=i;
for(int j=1;j<=cnt;j++)
b[j]=__gcd(b[j],a[i]);
int cn=0;
for(int j=1;j<=cnt;j++)
if(b[j]==b[j-1])r[cn]=r[j];else
{
b[++cn]=b[j];
l[cn]=l[j];
r[cn]=r[j];
}
cnt=cn;
ll p=0;
for(int j=cnt;j>=1;j--)
{
p=__gcd(p,b[j]);
ans=max(ans,((i-l[j]+1)*b[j]));
}
}
printf("%lld\n",ans);
return 0;
}