2019牛客暑期多校训练营(第八场)A All-one Matrices(单调栈)

题目链接
大意:给你一个01矩阵,求全1的极大子矩阵的个数
思路:我们考虑用单调栈解决,先预处理出每个1向上能延伸的最大高度 u [ i ] [ j ] u[i][j] u[i][j],然后我们枚举下边界,然后每个边界遍历每列,维护一个高度递增的单调栈,每个元素记录向左能延申到的最小位置 p o s pos pos,每次弹出的元素若满足向下无法延申的情况即可计入答案。

#include<bits/stdc++.h>

#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back

using namespace std;

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;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
const int N = 2e5 +11;
int n,m;
char a[3333][3333];
int u[3333][3333],sum[3333][3333];
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i]+1;
		for(int j=1;j<=m+1;j++){
			int x=j<=m?(a[i][j]=='1'):0;
			if(a[i][j]=='1'){
				u[i][j]=u[i-1][j]+1;
			}
			sum[i][j]=sum[i][j-1]+x;
		}
	}	
	int ans=0;
	for(int i=1;i<=n;i++){
		stack<pair<int,int> >q;
		int pos=-1,now=0;
		for(int j=1;j<=m+1;j++){
			int pos=j;
			while(!q.empty()&&u[i][j]<q.top().fi){
				auto x=q.top();
				q.pop();
				if(sum[i+1][j-1]-sum[i+1][x.se-1]!=j-x.se)ans++;
				pos=x.se;	
			}
			if(u[i][j]&&(q.empty()||q.top().fi<u[i][j]))q.push({u[i][j],pos});

		}
	}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值