P3865 ST表

题目链接

用途:对于一段区间的最大值 最小值 lcm等 用O(nlogn)预处理 O(1)查询

以本题为例:定义数组 rmq[i][j] 表示 \(i\) ~ \(i+2^k-1\) 区间内的最大值


预处理阶段类似LCA的倍增(This is LCA)

大循环是次数 以j-1为界限将一段区间分为两段:
image


然后是查询阶段 对于询问的一段区间 \([l,r]\) 这里我们选取一个最大的k 使得 $rmq[l][k] <= r $
实际上 \(k=\left\lfloor\log2(r-l+1)\right\rfloor\) 也好证:
image

且我们知道 两段子区间有重叠部分并不影响该区间最大值
image

所以我们取 \(2^k-1\) 长度的前缀和后缀作为两段子区间

用数组表示就是 rmq[l][k] 与 rmq[r+1-\(2^k\)][k]

且这两段区间一定是可以覆盖整个大区间的

我们可以使用反证法:假如这两段区间无法覆盖大区间 则 \(2^k-1\) 应小于区间长度 \(r-l+1\) 则此时取到的k就不是满足 $rmq[l][k] <= r $ 的最大值 与假设矛盾

查询代码如下:
image


附本题代码:
image

posted @ 2023-02-01 23:08  Steven24  阅读(19)  评论(1编辑  收藏  举报