美丽的序列

题目背景 Background
  GD是一个热衷于寻求美好事物的人,一天他拿到了一个美丽的序列。
 
 题目描述 Description
  为了研究这个序列的美丽程度,GD定义了一个序列的“美丽度”和“美丽系数”:对于这个序列的任意一个区间[l,r],这个区间的“美丽度”就是这个区间的长度与这个区间的最小值的乘积,而整个序列的“美丽系数”就是它的所有区间的“美丽度”的最大值。现在GD想要你帮忙计算这个序列的“美丽系数”。
 
输入输出格式 :Input/output
 
输入格式:
  第一行一个整数n,代表序列中的元素个数。
  第二行n个整数a1、a2…an,描述这个序列。
输出格式:
  一行一个整数,代表这个序列的“美丽系数”。
 
输入输出样例 Sample input/output
样例测试点#1
输入样例:

3
1 2 3

输出样例:
4
 
说明 description
样例解释
   选取区间[2,3],可以获得最大“美丽系数”为2*2=4。
数据范围
   对于20%的数据,n<=2000;
   对于60%的数据,n<=200000;
   对于100%的数据,1<=n<=2000000,0<=ai<=2000000。
提示
   你可能需要一个读入优化。
题解
  开两个单调队列,last[i]表示上一个比i小的值的位置,next[i]表示下一个比i小的值的位置,注意是小于,等于不算!!!
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 using namespace std;
 8 typedef long long LL;
 9 const LL inf=1e12;
10 inline LL read(){
11     LL x=0,f=1;char ch=getchar();
12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 LL N,a[2000001];
17 LL last[2000001],next[2000001];
18 LL q1[2000001],pos1[2000001],h1,t1;
19 LL q2[2000001],pos2[2000001],h2,t2;
20 inline void calc1();
21 inline void calc2();
22 LL maxx;
23 int main(){
24     N=read();
25     for(int i=1;i<=N;i++) a[i]=read();
26     calc1();
27     calc2();
28     for(int i=1;i<=N;i++){
29         LL tmp=(next[i]-last[i]-1)*a[i];
30         if(maxx<tmp) maxx=tmp;
31     }
32     cout<<maxx;
33     return 0;
34 }
35 inline void calc1(){
36     q1[1]=a[1];pos1[1]=1; h1=t1=1;
37     int now=2;
38     while(now<=N){
39         while(t1>=h1&&q1[t1]>=a[now]){
40             t1--;
41         }
42         t1++;
43         q1[t1]=a[now];
44         pos1[t1]=now;
45         last[now]=pos1[t1-1];
46         now++;
47     }
48 }
49 inline void calc2(){
50     q2[N]=a[N]; pos2[N]=N; h2=t2=N,next[N]=N+1;
51     int now=N-1;
52     while(now>=1){
53         while(t2<=h2&&q2[t2]>=a[now]){
54             t2++;
55         }
56         t2--;
57         q2[t2]=a[now];
58         pos2[t2]=now;
59         next[now]=pos2[t2+1];
60         if(next[now]==0) next[now]=N+1;
61         now--;
62     }
63 }

 

转载于:https://www.cnblogs.com/CXCXCXC/p/4904052.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值