小白月赛13 小A的柱状图 (单调栈)
链接:https://ac.nowcoder.com/acm/contest/549/H
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
柱状图是有一些宽度相等的矩形下端对齐以后横向排列的图形,但是小A的柱状图却不是一个规范的柱状图,它的每个矩形下端的宽度可以是不相同的一些整数,分别为a[i]a[i],每个矩形的高度是h[i]h[i],现在小A只想知道,在这个图形里面包含的最大矩形面积是多少。
输入描述:
一行一个整数N,表示长方形的个数
接下来一行N个整数表示每个长方形的宽度
接下来一行N个整数表示每个长方形的高度
输出描述:
一行一个整数,表示最大的矩形面积
备注:
1≤n≤1e6,1≤a[i]≤100,1≤h[i]≤1e91≤n≤1e6,1≤a[i]≤100,1≤h[i]≤1e9
解题思路:单调栈裸体,用两次单调栈求出对于每个小矩形的左右边界,遍历求出最大面积即可。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<set> #include<cmath> #include<list> #include<deque> #include<cstdlib> #include<bitset> #include<stack> #include<map> #include<cstdio> #include<queue> using namespace std; typedef long long ll; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1] const int INF=0x3f3f3f3f; const double PI=acos(-1.0); const double eps=1e-6; const ll mod=1e9+7; const int maxn=1000005; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; const int MAXN=1e6+10; int n,m,ans; stack<int> st; ll h[MAXN]; int a[MAXN],l[MAXN],r[MAXN]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); a[i]+=a[i-1]; } for(int i=1;i<=n;i++) scanf("%lld",&h[i]); for(int i=1;i<=n;i++){ while(st.size()&&h[st.top()]>=h[i])st.pop(); if(st.size()) l[i]=st.top(); else l[i]=0; st.push(i); } while(st.size())st.pop(); for(int i=n;i>=1;i--){ while(st.size()&&h[st.top()]>=h[i])st.pop(); if(st.size())r[i]=st.top()-1; else r[i]=n; st.push(i); } ll ans=0; for(int i=1;i<=n;i++){ ll tmp=h[i]*(a[r[i]]-a[l[i]]); if(tmp>ans)ans=tmp; } printf("%lld\n",ans); return 0; }