单调栈

Posted mdumpling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调栈相关的知识,希望对你有一定的参考价值。

描述:求一个数组的某一个数,向左右两边延申的最大区间,比如1276453.对于4可以向左延申到7,向右延申到5,也就是4在这个区间内是最小值。

适用:对于一个数组,如果对于全部区间去求解,需要n*(n-1)/2个区间,所以问题的复杂度至少是N的平方,如果换一个角度,所有的区间都是以某一个数字作为最小值的,所以只要求出一个数代表一个区间,就可以转换为O(n)的复杂度。

#include<stdio.h>
#include<math.h>
#include<iostream>
#include<stack>
using namespace std;
const int maxn=100010;
long long a[100010];
int l[100010],r[100010],n,ansl,ansr,top;

long long  sum[100010]={0},ans=-1;

int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
l[i]=r[i]=i;
} 
a[0]=a[n+1]=-1;

stack<int>s;   
for(i=1;i<=n+1;i++){
while(!s.empty()&&a[i]<=a[s.top()]  ){//a[i]<栈顶,出栈 
 r[s.top()] =i-1;//找出栈顶元素的下标右端点 
 s.pop();
}  
if(!s.empty())l[i]=s.top()+1;  
else l[i]=1;
   s.push(i);

} 

long long tmp;
for(i=1;i<=n;i++){

tmp=(sum[r[i]]-sum[l[i]-1])*a[i];
if(tmp>=ans){
ans=tmp;
ansl=l[i];
ansr=r[i];
} 
}
printf("%lld
", ans);
  printf("%d %d
", ansl, ansr);
return 0;
}

 

以上是关于单调栈的主要内容,如果未能解决你的问题,请参考以下文章

线性表--单调栈

线性表--单调栈

LeetCode- 柱状图中最大的矩形(单调栈)

HDU 6957 Maximal submatrix(悬线法 || 优先队列 || 单调栈 )

单调队列与单调栈作用

51nod1102(单调栈/预处理)