题解思路:
利用单调栈去找出每一个位置 i 左边第一个高度小于它的位置 L 和右边第一个高度小于它的位置 R ,然后在区间 (L,i] 所能取到的最大值即为h[ i ],这段区间对整体的贡献就是 (i - L) * h[ i ],对右边做同样处理,最后我们只需要找到它整体最大的那个位置即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define endl '
'
const int MAXN = 1e6+10;
const double EPS = 1e-12;
const ll mod = 1e9+7;
int n;
ll a[MAXN],l[MAXN],r[MAXN];
stack<int>st;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=1;i<=n;i++){
while(!st.empty()&&a[st.top()]>=a[i])st.pop();
if(st.empty())l[i]=a[i]*i;
else l[i]=l[st.top()]+a[i]*(i-st.top());
st.push(i);
}
while(!st.empty())st.pop();
for(int i=n;i>=1;i--){
while(!st.empty()&&a[st.top()]>=a[i])st.pop();
if(st.empty())r[i]=a[i]*(n-i+1);
else r[i]=r[st.top()]+a[i]*(st.top()-i);
st.push(i);
}
ll maxx=0,id=0;
for(int i=1;i<=n;i++){
if(l[i]+r[i]-a[i]>maxx){
maxx=l[i]+r[i]-a[i];
id=i;
}
}
for(int i=id-1;i>=1;i--)a[i]=min(a[i],a[i+1]);
for(int i=id+1;i<=n;i++)a[i]=min(a[i],a[i-1]);
for(int i=1;i<=n;i++)cout<<a[i]<<" ";
}