蓝书——131. 直方图中最大的矩形 单调栈入门题

回顾下单调栈。

单调栈的求解最大子矩形的核心思想就是枚举以每个高度作为矩形的高度,乘以最大宽度。

如果我们维护了一个递增的高度,来了一个比当前高度小的高度,那么当前高度就不能向右扩展了,则它就是一个无用高度,将它能扩展的宽度*高度算完就可以把他给扔了。

这样就能在线性时间处理类似问题

还有最大值左右维护的区间也可以用单调栈做,维护递增序列

最小值左右维护的区间,维护递减序列。

上面三类问题就是单调栈的经典问题,大部分题都是有上面变形得到,要抓住问题的本质,

#include 
using namespace std;
typedef long long ll;
//typedef __int128 LL;
//typedef unsigned long long ull;
//#define F first
//#define S second
typedef long double ld;
typedef pair pii;
typedef pair pll;
typedef pair pdd;
const ld PI=acos(-1);
const ld eps=1e-9;
//unordered_mapmp;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
//#define a(i,j) a[(i)*(m+2)+(j)]  //m是矩阵的列数
//pop_back()
const int seed=131;
const int M = 1e5+7;
/*
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y,int z){ee[++cnt].nxt=head[x],ee[cnt].to=y,ee[cnt].val=z,head[x]=cnt;}
*/
int a[M];
int s[M],w[M];
int main()
{
//	ios::sync_with_stdio(false);
//  	cin.tie(0);
	int n;
	while(scanf("%d",&n)&&n)
	{
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		ll ma=0;
		int p=0;
		a[n+1]=s[p]=0;
		for(int i=1;i<=n+1;i++)
		{
			if(a[i]>=s[p])s[++p]=a[i],w[p]=1;
			else
			{
				int wi=0;
				while(a[i]

 

你可能感兴趣的:(算法竞赛——进阶指南)