压位单调栈实现线性 rmq
还是分块 st 表(令块长为 \(B\)),不同的是块内的操作。我们预处理出每个块的前后缀最值,于是要解决的就只有 \(l,r\) 均落在同一块内的情况。有一个单调栈做法是处理出每个前缀的单调栈情况(存储下标),于是询问 \([l,r]\) 就变成了在 \(r\) 所对应的前缀的单调栈里二分查找第一个大于等于 \(l\) 的元素。
这样做的复杂度显然是不对的,但我们可以把每个单调栈压成 bitset, \(stk_i=1\) 就代表着当前单调栈里有 \(i\) 这个元素。于是 .back() 就等价于 highbit,其余操作也可以用相应的位运算表示。唯一麻烦的是二分,这个似乎有一些奇妙的科技能使得它做到 \(O(1)\),但其实 \(\log(B)\) 和 \(O(1)\) 也差不了多少,不是吗(。