题目背景 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 }
时间: 2024-10-06 22:56:33