分别建立区间最小值和最大值 ST 表,让每次静态区间极差查询 O(1) 完成。
OJ: luogu
题目 ID: P2880
难度:普及/提高-
标签:ST表区间最值python
日期: 2026-01-17 20:25
题意
静态数组上回答大量区间最高值减最低值。
思路
ST 表第 level 层保存长度 [l,r] 时取 level=floor(log2(length)),用左右两个允许重叠的长度 min/max 满足幂等性,重叠不会影响答案。
Python 知识
array("i")紧凑保存各层数据,两个 ST 表总共只需个 32 位整数。 - 生成器直接构造下一层数组,不创建额外列表。
- 预处理
logs[length]后,每次询问只做常数次下标访问。
代码
python
import sys
from array import array
data = iter(map(int, sys.stdin.buffer.read().split()))
n, queries = next(data), next(data)
heights = array("i", (next(data) for _ in range(n)))
logs = [0] * (n + 1)
for i in range(2, n + 1):
logs[i] = logs[i // 2] + 1
minimum = [heights]
maximum = [heights]
level = 1
while 1 << level <= n:
half = 1 << (level - 1)
length = n - (1 << level) + 1
previous_min, previous_max = minimum[-1], maximum[-1]
minimum.append(array("i", (min(previous_min[i], previous_min[i + half])
for i in range(length))))
maximum.append(array("i", (max(previous_max[i], previous_max[i + half])
for i in range(length))))
level += 1
answers = []
for _ in range(queries):
left, right = next(data) - 1, next(data) - 1
level = logs[right - left + 1]
start = right - (1 << level) + 1
high = max(maximum[level][left], maximum[level][start])
low = min(minimum[level][left], minimum[level][start])
answers.append(str(high - low))
print("\n".join(answers))复杂度
预处理
总结
静态、可重叠的区间最值查询是 ST 表的标准使用场景。