您的位置:首页 > 其它

luogu P2659 美丽的序列

2017-10-23 18:54 253 查看

题目背景

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。 提示 你可能需要一个读入优化。

用线段树+维护区间最小值,构造一颗笛卡尔树+卡时可以过

#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn= 2000007;
#ifdef WIN32
#define lld "I64d"
#else
#define lld "lld"
#endif
inline int read() {
int x=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();return x;
}
int a[maxn],b[maxn];
int l[maxn],r[maxn],tmp[maxn],q[maxn];
int n,m;
void work(int c[] ,int d[]) {
q[1]=c[1]; tmp[1]=1;
int head=1,tail=1;
for(int i=2;i<=n;++i) {
while(head<=tail&&q[tail]>c[i]) d[tmp[tail--]]=i-1;
q[++tail]=c[i];
tmp[tail]=i;
}
while(head<=tail) d[tmp[head++]]=n;
}
int main() {
LL ans=0;
n=read();
for(int i=1;i<=n;++i)
a[i]=read(),b[n-i+1]=a[i];
work(a,r);
work(b,l);
for(int i=1;i<=n;++i) tmp[i]=l[i];
for(int i=1;i<=n;++i) l[n-i+1]=n-tmp[i]+1;
for(int i=1;i<=n;++i) ans=max(ans,1ll*a[i]*(r[i]-l[i]+1));
printf("%lld\n",ans);
return 0;
}


单调队列
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: