HUNAU2020-栈与单调栈(E - Largest Rectangle in a Histogram)
E - Largest Rectangle in a Histogram.
单调栈:
定义:栈内元素具有单调性,如果新入栈元素破坏了单调性,就弹出栈内元素,直到满足单调性
作用:方便求出某个数左右第一个比他小或大的元素,时间复杂度O(N)
#include <iostream>
#include <stack>
#include <stdio.h>
#define MAX 1000005
using namespace std;
int l[MAX];//用于记录左边第一个水平线比本身低的矩形的数组索引
int r[MAX];//用于记录右边第一个水平线比本身低的矩形的数组索引
long long int value[MAX];//存储每个矩形的高度
//本题的单调栈为严格单调递增栈,才为第一个不能拓展的位置
int main()
{
int n;
while (scanf("%d", &n) && n)
{
stack<int> a;//用一个a的单调递增栈来方便查找左边第一个不能拓展的矩形下标
stack<int> b;//用一个b的单调递增栈来方便查找右边第一个不能拓展的矩形下标
value[n + 1] = value[0] = 0;//将最左边和最右边设为高度为0便于记录下标
for (int i = 1; i <= n; i++)
{
scanf("%lld", &value[i]);
while (!a.empty() && value[a.top()] >= value[i])//当栈顶元素小于value[i]则出栈,直到留下小于value[i]的元素保持栈的单调递增
a.pop();
if (a.empty())
l[i] = 0;//当栈为空即已找到最左边的位置0,高度为0
else
l[i] = a.top();//取栈顶元素为左边第一个不能拓展矩形的位置
a.push(i);
}
for (int i = n; i > 0; i--)
{
while (!b.empty() && value[b.top()] >= value[i])
b.pop();
if (b.empty())
r[i] = n + 1;//当栈为空即已找到最右边的位置n+1,高度为0
else
r[i] = b.top();//取栈顶元素为右边第一个不能拓展矩形的位置
b.push(i);
}
long long int max = -1;
//max用于存储最大矩形的面积(面积必大于0),tips提醒可能数据会超过int
for (int i = 1; i <= n; i++)
//逐个比较每个位置矩形能拓展的最大面积,能拓展的最大长度为r[i]-l[i]-1
if (max < value[i] * (r[i] - l[i] - 1))
{
max = value[i] * (r[i] - l[i] - 1);
}
printf("%lld\n", max);
}
return 0;
}