用单调递减队列保留窗口最大值候选,并以紧凑数组支持两百万规模输入。
OJ: luogu
题目 ID: P2032
难度:普及/提高-
标签:单调队列滑动窗口python
日期: 2025-12-26 19:31
题意
输出序列中每个长度为
思路
队列保存值严格递减的候选。新数加入时,队尾所有不大于它的旧数更早过期且更小,可以永久删除;队头下标离开窗口时删除。窗口形成后队头就是最大值。
Python 知识
可达两百万,使用两个 array("i")模拟紧凑双端队列,避免大量 Python 元组。os.read分块解析整数,避免read().split()的峰值内存。- 答案按 8192 行分块写出,避免保存全部输出字符串。
代码
python
import os
import sys
from array import array
def read_ints():
number = 0
reading = False
while chunk := os.read(0, 1 << 20):
for byte in chunk:
if 48 <= byte <= 57:
number = number * 10 + byte - 48
reading = True
elif reading:
yield number
number = 0
reading = False
if reading:
yield number
data = iter(read_ints())
n, window = next(data), next(data)
indices = array("i", [0]) * n
values = array("i", [0]) * n
head = tail = 0
output = []
write = sys.stdout.write
for i in range(n):
value = next(data)
while head < tail and indices[head] <= i - window:
head += 1
while head < tail and values[tail - 1] <= value:
tail -= 1
indices[tail] = i
values[tail] = value
tail += 1
if i >= window - 1:
output.append(str(values[head]))
if len(output) == 8192:
write("\n".join(output) + "\n")
output.clear()
if output:
write("\n".join(output) + "\n")复杂度
时间复杂度
总结
滑动窗口最值只需保留尚未过期且没有被更优新元素淘汰的候选。