【洛谷P2659】美丽的序列

 

题目背景

GD是一个热衷于寻求美好事物的人,一天他拿到了一个美丽的序列。

题目描述

为了研究这个序列的美丽程度,GD定义了一个序列的“美丽度”和“美丽系数”:对于这个序列的任意一个区间[l,r],这个区间的“美丽度”就是这个区间的长度与这个区间的最小值的乘积,而整个序列的“美丽系数”就是它的所有区间的“美丽度”的最大值。现在GD想要你帮忙计算这个序列的“美丽系数”。

输入输出格式

输入格式:

 

第一行一个整数n,代表序列中的元素个数。 第二行n个整数a1、a2„an,描述这个序列。

 

输出格式:

 

一行一个整数,代表这个序列的“美丽系数”。

 

输入输出样例

输入样例#1:
3 
1 2 3
输出样例#1:
4

说明

样例解释 选取区间[2,3],可以获得最大“美丽系数”为2*2=4。 数据范围 对于20%的数据,n<=2000; 对于60%的数据,n<=200000; 对于100%的数据,1<=n<=2000000,0<=ai<=2000000。 提示 你可能需要一个读入优化。

题解

暴力的话一定会超时,我们先固定最小值,然后找出以这个值为最小值的最大区间,然后枚举就行了。不要忘记开long long!

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=2000000+5;
inline int read()
{
    int 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*10+ch-'0';ch=getchar();}
    return x*f;
}
int n;
int a[maxn],l[maxn],r[maxn];
ll ans=-1;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) 
    {
        a[i]=read();
        l[i]=r[i]=i;
    }
    a[0]=a[n+1]=-1;
    for(int i=1;i<=n;i++)
    {
        int j=i-1;
        while(a[j]>=a[i])
        {
            l[i]=l[j];
            j=l[j]-1;
        }
    }
    for(int i=n;i>=1;i--)
    {
        int j=i+1;
        while(a[j]>=a[i])
        {
            r[i]=r[j];
            j=r[j]+1;
        }
    }
    for(int i=1;i<=n;i++)
    {
        ll tmp=(ll)(r[i]-l[i]+1)*(ll)a[i];
        ans=max(tmp,ans);
    }
    printf("%lld
",ans);
    return 0;
}

 

原文地址:https://www.cnblogs.com/bahl/p/7294517.html