Description
给定一个长度为 N 的正整数序列Ai对于其任意一个连续的子序列
{Al,Al+1…Ar},我们定义其权值W(L,R )为其长度与序列中所有元素的最大公约数的乘积,即W(L,R) = (R-L+1) ∗ gcd (Al..Ar)。
JYY 希望找出权值最大的子序列。
题解:
结论:固定右端点
r
,左端点
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int Maxn=100010;
LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
int n;
LL a[Maxn];
LL gcd(LL a,LL b){return((b==0)?a:gcd(b,a%b));}
struct A{int x;LL g;}f[2][Maxn];
bool cmp(A a,A b){return((a.g==b.g)?a.x<b.x:a.g<b.g);}
int main()
{
LL ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)a[i]=read();
int l=0,now=1,last=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=l;j++)f[last][j].g=gcd(f[last][j].g,a[i]);
f[last][++l].g=a[i];f[last][l].x=i;
sort(f[last]+1,f[last]+1+l,cmp);
int ll=0;f[last][0].g=-1;
for(int j=1;j<=l;j++)
if(f[last][j-1].g!=f[last][j].g)f[now][++ll]=f[last][j];
for(int j=1;j<=ll;j++)ans=max(ans,(LL)(i-f[now][j].x+1)*f[now][j].g);
l=ll;last^=1;now^=1;
}printf("%lld",ans);
}