NC23619 小A的柱状图

题目

题目描述

柱状图是有一些宽度相等的矩形下端对齐以后横向排列的图形,但是小A的柱状图却不是一个规范的柱状图,它的每个矩形下端的宽度可以是不相同的一些整数,分别为 \(a[i]\) ,每个矩形的高度是 \(h[i]\) ,现在小A只想知道,在这个图形里面包含的最大矩形面积是多少。

img

输入描述

一行一个整数N,表示长方形的个数
接下来一行N个整数表示每个长方形的宽度
接下来一行N个整数表示每个长方形的高度

输出描述

一行一个整数,表示最大的矩形面积

示例1

输入

7
1 1 1 1 1 1 1
2 1 4 5 1 3 3

输出

8

说明

样例如图所示,包含的最大矩形面积是8

备注

\(1 \leq n \leq 1e6 , 1\leq a[i] \leq 100 ,1\leq h[i] \leq 1e9\)

题解

知识点:单调栈,前缀和。

这道题一样枚举直方图高度并用单调栈获得每个直方区间最大伸展量。但是,区间长度并不能通过下标直接计算,需要前缀和预处理计算。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long

using namespace std;

int a[1000007], h[1000007], l[1000007], r[1000007];

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1;i <= n;i++) cin >> a[i], a[i] += a[i - 1];
    for (int i = 1;i <= n;i++) cin >> h[i];
    stack<int> s1, s2;
    for (int i = 1;i <= n;i++) {
        while (!s1.empty() && h[s1.top()] >= h[i]) s1.pop();
        l[i] = s1.empty() ? 1 : s1.top() + 1;
        s1.push(i);
    }
    for (int i = n;i >= 1;i--) {
        while (!s2.empty() && h[s2.top()] >= h[i]) s2.pop();
        r[i] = s2.empty() ? n : s2.top() - 1;
        s2.push(i);
    }
    ll ans = 0;
    for (int i = 1;i <= n;i++)
        ans = max(ans, 1LL * (a[r[i]] - a[l[i] - 1]) * h[i]);
    cout << ans << '\n';
    return 0;
}
posted @ 2022-07-02 22:06  空白菌  阅读(27)  评论(0)    收藏  举报