Advertisement

Advertisement

借用nearest smaller values的想法,对任何一个数xx,都可以求出左侧和右侧最近的小于xx的数的位置ll,rr,则以xx为最小高度的广告的最大面积是 (rl1)x(r-l-1) x,对所有xx求最大值就可以了。

这个方法比较容易理解,可以进一步优化成一遍扫描:就是用堆栈记录{l[i], height[i]},其中l[i]就是上面的ll,然后在每个位置计算所有rr在当前位置的广告牌大小(就是pop掉所有比当前height高的记录)。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
int n;
stack<pair<int,int>> st;
vector<int> x, l,r;
 
int main() {
    scanf("%d", &n);
    x.resize(n+5,0); l.resize(n+5,0); r.resize(n+5,0);
    for (int i = 1; i <= n; i++) scanf("%d", &x[i]);
    st.push({0,0});
    for (int i = 1; i <= n; i++) {
        while (st.top().first >= x[i]) st.pop();
        l[i] = st.top().second;
        st.push({x[i],i});
    }
    st = stack<pair<int,int>>();
    st.push({0,n+1});
    for (int i = n; i >= 1; i--) {
        while (st.top().first >= x[i]) st.pop();
        r[i] = st.top().second;
        st.push({x[i],i});
    }
    ll ans = 0;
    for (int i = 1; i <= n; i++)
        ans = max(ans, (ll)(r[i]-l[i]-1)*x[i]);
    printf("%lld", ans);
    return 0;
}