🧀 🧀 🧀
为什么当时没有静下心多想一步呢,,,哦对因为到饭点了
//某点做最高峰,
//左边的贡献值:左边第一个小于等于他的点的predp+m[i]*这两点之间的距离
//右边的贡献值:右边第一个小于等于他的点的sufdp+m[i]*这两点的距离
#define int ll
int n,a[MAXN];
int pre[MAXN],suf[MAXN];
int predp[MAXN],sufdp[MAXN];
stack<int>st;
void solve()
{
cin>>n;
rpp(i,n) cin>>a[i];
//求前面第一个小于等于的
rpp(i,n)
{
while(st.size()&&a[st.top()]>a[i]) st.pop();
if(st.empty()) pre[i]=0;
else pre[i]=st.top();
st.push(i);
}
//求后面第一个小于等于的
while(st.size()) st.pop();
for(int i=n;i>=1;--i)
{
while(st.size()&&a[st.top()]>a[i]) st.pop();
if(st.empty()) suf[i]=n+1;
else suf[i]=st.top();
st.push(i);
}
//求出predp
for(int i=1;i<=n;++i) predp[i]=predp[pre[i]]+a[i]*(i-pre[i]);
for(int i=n;i>=1;--i) sufdp[i]=sufdp[suf[i]]+a[i]*(suf[i]-i);
int mx=0,ans=1;
rpp(i,n) if(predp[i]+sufdp[i]-a[i]>mx) mx=predp[i]+sufdp[i]-a[i],ans=i;
for(int i=ans-1;i>=1;--i) a[i]=min(a[i],a[i+1]);
for(int i=ans+1;i<=n;++i) a[i]=min(a[i],a[i-1]);
rpp(i,n) cout<<a[i]<<" ";
cout<<endl;
}
signed main()
{
fast;
solve();
return 0;
}