ST 表(稀疏表)
静态区间最值:预处理 O(n log n),查询 O(1)。诀窍——用两段 2^k 长的区间盖住询问,重叠也没关系。
一、互动演示:O(1) 查询区间最大值
数组下标 1~8。输入 l, r,看它如何用两段长度 2^k的区间(一段贴左、一段贴右)覆盖 [l,r];重叠部分(紫色)不影响最大值。
点“查询”,看两段 2^k 区间如何拼出答案。
二、构建与查询代码
// 构建:f[i][j] = 从 i 起长 2^j 的区间最大值
for (int i = 1; i <= n; i++) f[i][0] = a[i];
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
f[i][j] = max(f[i][j-1], f[i + (1 << (j-1))][j-1]);
// 查询 [l, r]:取两段 2^k 覆盖,允许重叠
int k = log2(r - l + 1);
int ans = max(f[l][k], f[r - (1 << k) + 1][k]);
"重叠不影响"只对 max/min/gcd 这类可重复贡献的运算成立;求和要用前缀和或线段树。仅静态数组可用。