单调栈+前缀和 || Nowcoder || 牛客小白月赛13 || 小A的柱状图

时间:2022-11-23 21:51:14

题面:小A的柱状图

题解:无

代码:

 #include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
inline ll rd(){
ll x=;char c=getchar();
while(c<''||c>''){c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x;
}
const ll maxn=(1e6)+;
ll N,A[maxn],H[maxn],sig[maxn],S[maxn],L[maxn],R[maxn],top,ans;
//前缀和维护A[i]
//用两个单调栈,分别从左往右和从右往左找出第一个小于H[i]的数的位置
int main(){
N=rd();
for(int i=;i<=N;i++){
A[i]=rd();
sig[i]=sig[i-]+A[i];
}
for(int i=;i<=N;i++){
H[i]=rd();
ans=max(ans,A[i]*H[i]);
}
top=;S[top]=;L[]=;
for(int i=;i<=N;i++){
while(top>=&&H[S[top]]>=H[i])top--;
L[i]=S[top];
S[++top]=i;
}
top=;S[top]=N;R[N]=;
for(int i=N-;i>=;i--){
while(top>=&&H[S[top]]>=H[i])top--;
R[i]=S[top];
if(R[i]==)R[i]=N+;
S[++top]=i;
}
for(int i=;i<=N;i++)
ans=max(ans,(sig[R[i]-]-sig[L[i]])*H[i]);
printf("%lld\n",ans);
return ;
}

By:AlenaNuna