全零子矩形计数问题

经典问题,但是我为什么不会呢?????

题意

给定一张 n×m 的 01 矩阵,求出有多少个子矩阵使得子矩阵内没有 1。

n,m103

分析

考虑枚举每一行,计算以该行上每个点为右下角的合法子矩形个数 sumi,j,也就是说,计算左上角的个数使得左上角和该右下角形成的子矩形不包含 1。

其实到这里已经可以思考单调栈了,但是为了捋顺思路,我们还是考虑对于每一行,只有该列上方的第一个 1 会对子矩形大小产生限制,而在某一个 1 往左的比该 1 所在行数要靠前的那些 1 也不会产生限制。据此我们考虑单调栈,预处理 upi,j 表示 (i,j) 往上第一个 1 和它本身的距离,单调栈里维护一个递增的 upi,jsumi,j,将比 upi,j 大的点弹完后,令栈顶的列为 c,由于单调栈 up 递增,sumi,c 的答案可以直接继承到 sumi,j 中,额外的贡献还有 x(upi,c,upi,j],y(c,j] 这部分子矩形的点,把它们加进 sumi,j 中。

时间复杂度 O(nm)

rep(j,1,m){
	rep(i,1,n){
		if(s[i][j]=='1')up[i][j]=0;
		else up[i][j]=up[i-1][j]+1;
	}
}
int ans=0;
rep(i,1,n){
	tp=0;
	sum[0]=0;
	rep(j,1,m){
		while(tp&&up[i][j]<=up[i][sta[tp]])--tp;
		sum[j]=(sum[sta[tp]]+1ll*(j-sta[tp])*up[i][j]%mod)%mod;
		ans=(ans+sum[j])%mod;
		sta[++tp]=j;
	}
}

作者:dcytrl

出处:https://www.cnblogs.com/dcytrl/p/18538111

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   dcytrl  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示