小A的柱状图

思路

经典的单调栈题目,对于每一个位置,我们维护他以当前高度可以到达的最左方,以及他当前高度可以到达的最有方,显然就有以他的高度的矩形块的面积就出来了,所以我们只需要统计n个矩形的最大值就行。

具体细节操作看代码注释。

代码

/*
  Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define endl '\n'

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;

inline ll read() {
    ll f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f * x;
}

void print(ll x) {
    if(x < 10) {
        putchar(x + 48);
        return ;
    }
    print(x / 10);
    putchar(x % 10 + 48);
}

const int N = 1e6 + 10;

int h[N], len[N], l[N], r[N], n;

stack<int> stk;

int main() {
    //freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    n = read();
    for(int i = 1; i <= n; i++) {
        len[i] = len[i - 1] + read();
    }
    for(int i = 1; i <= n; i++) {
        h[i] = read();
    }
    for(int i = 1; i <= n; i++) {
        while(stk.size() && h[stk.top()] >= h[i]) stk.pop();
        if(stk.empty()) l[i] = 1;
        else l[i] = stk.top() + 1;
        stk.push(i);
    }
    while(stk.size()) stk.pop();
    for(int i = n; i >= 1; i--) {
        while(stk.size() && h[stk.top()] >= h[i]) stk.pop();
        if(stk.empty()) r[i] = n;
        else r[i] = stk.top() - 1;
        stk.push(i);
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++) {
        ans = max(ans, 1ll * (len[r[i]] - len[l[i] - 1]) * h[i]);
    }
    printf("%lld\n", ans);
    return 0;
}