列表

详情


NC20217. [JSOI2015]最大公约数

描述

给定一个长度为 N 的正整数序列Ai对于其任意一个连续的子序列 {Al,Al+1...Ar},我们定义其权值W(L,R )为其长度与序列中所有元素的最大公约数的乘积,即W(L,R) = (R-L+1) ∗ gcd (Al..Ar)。 JYY 希望找出权值最大的子序列。

输入描述

输入一行包含一个正整数 N。 接下来一行,包含 N个正整数,表示序列Ai, 1 < =  Ai < =  10^12, 1 < =  N < =  100,000

输出描述

输出文件包含一行一个正整数,表示权值最大的子序列的权值。

示例1

输入:

5
30 60 20 20 20

输出:

80
//最佳子序列为最后 4 个元素组成的子序列。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 28ms, 内存消耗: 1200K, 提交时间: 2022-01-13 22:49:08

#include<bits/stdc++.h>
typedef long long ll;
const ll INF=0x3f3f3f3f;
const int MAXN=1e5+5;
using namespace std;
inline ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a;
}
ll col[MAXN],gc[MAXN],a[MAXN];
int main()
{
	ll ans=-INF;
	int k=0,n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++)
	{
		col[++k]=i;
		gc[k]=a[i];
		for(int j=k-1;j>=1;j--)
		gc[j]=gcd(gc[j],gc[j+1]);
		int cot=0;
		for(int j=1;j<=k;)
		{
			gc[++cot]=gc[j];
			col[cot]=col[j];
			while(gc[cot]==gc[j]) j++;
		}
		k=cot;
		for(int j=1;j<=k;j++)
		ans=max(ans,gc[j]*(i-col[j]+1));
	}
	printf("%lld",ans);
	return 0;
}

上一题