所谓(RMQ),就是(Range) (Minimum/Maximum) (Query),区间最值查询。我们可以用线段树维护,也可以使用笛卡尔树将其转化为求(lca)的问题。但是后者一般不常用,更为常用的,是家喻户晓的(st)算法。由于(RMQ)问题大多不是赤裸裸的(RMQ),而是经过了伪装。所以(st)算法显得尤为重要。
嗯,我也不清楚这有什么关系。但是先不说能不能看破(RMQ)的伪装,(st)算法总得会嘛,(st)都不会看破伪装不照样(GG)……
(st)算法
(st)算法用了(dp)的思想,我们设(f[i][j])表示从当前序列第(i)位开始,一直到(i+2^j-1)结束最大值在哪一位。
那么(f[i][j])就可以由(f[i][j-1])与(f[i+2^j][j-1])更新得来。预处理(f)数组需要(O(nlogn))的时间。
求出(f)数组之后,我们就可以(O(1))的查询区间([l,r])的最大值了。设(len=r-l+1),假设存在一个(x)满足:
(2^xleqslant len)且(lenleqslant 2^{x+1})。那么(f[l][x])与(f[r-2^x+1][x])的最大值就是区间([l,r])的最大值。因为([l,l+2^x-1])与([r-2^x+1,r])肯定会将区间([l,r])覆盖,即使重合了也没关系,最大值还是最大值。我还是菜鸡
(st)算法会了之后就可以愉快的去写(RMQ)了。如果你看不破题目的伪装,那就去与(RMQ)的战场上走一遭吧,能活着回来你就会了。