思路:从左到右求一遍单调栈,,每次维护前缀,再倒着来一次。
int a[N];
ll p[N], fp[N];
int main()
{
//freopen("in.txt", "r", stdin);
int n;
while (cin >> n)
{
f(i, 1, n)scanf("%d", &a[i]);
stack<int> st;
f(i, 1, n)//从左到右求一遍单调栈,递增
{
while (!st.empty() && a[st.top()] >= a[i])st.pop();
int start;
if (st.empty())start = 0;
else start = st.top();
p[i] = p[start] + ll(i - start)*a[i];
st.push(i);
}
//f(i, 1, n)cout << p[i] << endl;
while (!st.empty())st.pop();
ff(i, n, 1)
{
while (!st.empty() && a[st.top()] >= a[i])st.pop();
int start;
if (st.empty())start = n + 1;
else start = st.top();
fp[i] = fp[start] + (ll)(start - i)*a[i];
st.push(i);
}
//ff(i, n, 1)cout << fp[i] << endl;
ll mx = 0;
int id = 0;
f(i, 1, n)
{
if (p[i] + fp[i] - a[i] > mx) { mx = p[i] + fp[i] - a[i];id = i; }
}
ff(i, id - 1, 1)a[i] = min(a[i], a[i + 1]);
f(i,id+1,n)a[i]=min(a[i],a[i-1]);
f(i, 1, n)cout << a[i] << " ";
cout << endl;
}
return 0;
}