题目链接
单调栈维护出每个点左边最大值和右边最大值就行
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[500005];
int sum[500005];
int sum1[500005];
signed main()
{
int n;
cin >> n;
for(int i = 1; i <= n;i ++){
cin >> a[i];
}
stack<int> st;
a[0] = 0;
a[n + 1] = 0;
st.push(0);
for(int i = 1; i <= n; i ++){
if(!st.size()||a[st.top()] <= a[i]){
st.push(i);
sum[i] = sum[i - 1] + a[i];
}
else{
while(st.size()&& a[st.top()] > a[i]){
st.pop();
}
sum[i] = sum[st.top()] + (i - st.top())*a[i];
st.push(i);
}
}
while(st.size()) st.pop();
st.push(n + 1);
sum1[n + 1] = 0;
for(int i = n; i >= 1; i --){
if(!st.size() || a[st.top()] <= a[i]){
sum1[i] = sum1[i + 1] + a[i];
st.push(i);
}
else{
while(st.size()&&a[st.top()] > a[i]){
st.pop();
}
sum1[i] = sum1[st.top()]+(st.top() - i)*a[i];
st.push(i);
}
}
int id = 1;
for(int i = 2; i <= n; i ++){
if(sum[i] + sum1[i] - a[i] > sum[id] + sum1[id] - a[id]){
id = i;
}
}
for(int i = id; i >= 2; i --){
if(a[i] < a[i - 1]){
a[i - 1] = a[i];
}
}
for(int i = id; i <= n - 1; i ++){
if(a[i] < a[i + 1]){
a[i + 1] = a[i];
}
}
for(int i = 1; i <= n; i ++){
cout << a[i] <<" ";
}
cout << endl;
}