【单调栈】

【单调栈】

定义

image

模版代码

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n;
int tt;
long long stk[N];
long long x;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%lld",&x);
		//栈首先要不为空 
		while(tt && stk[tt]>=x) tt--;
		if(tt) printf("%lld ",stk[tt]);
		else printf("-1 ");
		stk[++tt]=x;
	}
	return 0;
}

模版题

https://www.luogu.com.cn/problem/P2866

/*【思路】
比当前加进来的矮的->弹出
剩下的就是【当前在栈里】能看到这个数的(求一头牛能被多少头牛看见) 
->再加进栈里 
*/ 
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N=80010;
int n;
int a[N],stk[N];
int cnt=-1;
signed main(){
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      cin>>n;
      for(int i=1;i<=n;i++){
      	cin>>a[i];
      }
      ll ans=0;
      for(int i=1;i<=n;i++){
				//注意这里是严格递减->保持单调性! 
      	while(cnt>=0 && stk[cnt]<=a[i]) cnt--;
      	ans+=cnt+1;
      	stk[++cnt]=a[i];
	}
	cout<<ans; 
      return 0;
}

应用

求最大子矩阵面积

City Game

https://fjnuacm.top/d/minor/p/226?tid=66bcba9e7d902b243e152ae7

举例

image
image
image

代码
/*【单调栈求最大子矩形面积(变式)】
 对于每一行 看做一个矩形 
 */ 
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=1010;
int n,m;
string a;
int f[N][N],h[N][N],s[N],w[N];//h高度 s高度栈 w宽度栈
int p=0,ans=-1; 
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a;
			if(a[0]=='R') f[i][j]=0;
			else if(a[0]=='F') f[i][j]=1;
		}
	}
	//预处理
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(f[i][j]) h[i][j]=h[i-1][j]+1;//高度累加 
		}
	}
	//单调栈:对于每一行都按照最大子矩形面积做一遍 
	for(int i=1;i<=n;i++){//每一行 
		memset(s,0,sizeof s);
		memset(w,0,sizeof w);
		for(int j=1;j<=m+1;j++){//列遍历:最后要0收尾 
			if(s[p]<=h[i][j]){
				s[++p]=h[i][j];
				w[p]=1;
			}
			else{
				//在出栈时计算以当前出栈元素为高度的矩形的最大宽度 
				int wid=0;
				while(s[p]>h[i][j]){
					wid+=w[p];//累加:给后面的用(后面的<=都可以用前面长的) 
					ans=max(ans,wid*s[p]);
					p--;
				}
				s[++p]=h[i][j];
				w[p]=wid+1;
			}
		}
	}
	printf("%d",ans*3);
	return 0;
}
posted @ 2025-01-21 11:21  White_ink  阅读(4)  评论(0)    收藏  举报