小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; }