逐行构造空白高度,并用单调栈求所有以当前行结底的空白矩形数量。
OJ: luogu
题目 ID: P1950
难度:普及+/提高
标签:单调栈组合计数矩阵python
日期: 2026-07-16 18:25
题意
统计网格中完全由 . 组成的轴对齐子矩形数量。
思路
逐行维护每列连续空白高度。固定当前行为矩形下边界时,选择一段连续列的可选高度数等于这段高度的最小值,所以要计算直方图所有子数组最小值之和。
递增栈保存 (height, width_count)。弹出更高或相等项时,从 ending_here 中删掉它对所有对应左端点的贡献,并把这些左端点合并给当前高度。每处理一列,ending_here 就是所有以该列结尾矩形数。
Python 知识
- 直接遍历字节行,
.的字节值是 46,省去字符解码。 - 栈中把相同高度用
width_count合并,避免逐个左端点维护。 - Python 整数可直接保存最多约
的答案。
代码
python
import sys
input = sys.stdin.buffer.readline
rows, columns = map(int, input().split())
heights = [0] * columns
answer = 0
for _ in range(rows):
for j, cell in enumerate(input().strip()):
heights[j] = heights[j] + 1 if cell == 46 else 0
stack = []
ending_here = 0
for height in heights:
width = 1
while stack and stack[-1][0] >= height:
previous_height, previous_width = stack.pop()
ending_here -= previous_height * previous_width
width += previous_width
stack.append((height, width))
ending_here += height * width
answer += ending_here
print(answer)复杂度
时间复杂度
总结
矩形计数转成“每行直方图的所有子数组最小值之和”。