Codeforces Round #622 (Div. 2) C. Skyscrapers
单调栈维护下每个位置向前向后单调的最大和
const int maxn = 5e5 + 7;
#define int long long
int n, t, m;
int a[maxn], pre[maxn], suf[maxn];
stack<pair<int, int>> st;
void solve() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++) {
if (st.size() == 0 || a[i] > st.top().first) {
st.push({a[i], 1});
pre[i] = pre[i - 1] + a[i];
} else {
pair<int, int> nex = {a[i], 1};
pre[i] = pre[i - 1] + a[i];
while (st.size() && st.top().first > a[i]) {
auto tp = st.top();
st.pop();
pre[i] -= (tp.first - a[i]) * tp.second;
nex.second += tp.second;
}
st.push(nex);
}
}
while (st.size()) st.pop();
for (int i = n; i >= 1; i--) {
if (st.size() == 0 || a[i] > st.top().first) {
st.push({a[i], 1});
suf[i] = suf[i + 1] + a[i];
} else {
pair<int, int> nex = {a[i], 1};
suf[i] = suf[i + 1] + a[i];
while (st.size() && st.top().first > a[i]) {
auto tp = st.top();
st.pop();
suf[i] -= (tp.first - a[i]) * tp.second;
nex.second += tp.second;
}
st.push(nex);
}
}
int ans = 0, pl = 0;
for (int i = 1; i <= n; i++)
if (suf[i] + pre[i] - a[i] > ans)
ans = suf[i] + pre[i] - a[i], pl = i;
for (int i = pl + 1; i <= n; i++)
a[i] = min(a[i], a[i - 1]);
for (int i = pl - 1; i >= 1; --i)
a[i] = min(a[i], a[i + 1]);
for (int i = 1; i <= n; i++)
cout << a[i] << " ";
}
我看见 你