RMQ,即range minimum queuy,范围最小值查询,一般朴素算法查询单个区间是O(n),查询m个就是O(m*n) ,这里要说的Sparse-Table算法,需要O(nlog n)的预处理,O(1)的单次查询,在查询次数很多的时候就能体现更好的优越性。而且,最重要的是这个算法写法简单,理解方便~~
令d(i,j)表示从i开头的,长度为2^j(本文中^都表示次方而不是异或)的区间内的最小值,则可以使用递推来求d(i,j):
这不难理解啊,直接将2^j个元素分两半了,然后取左边2^(j-1)个元素的最小值和2^(j-1)个元素的最小值的最小值~显然这个递推是O(1)的,然后i有n个,由于2^j <= n,也就是 j <= log n,所以d数组有不超过nlog n个元素,所以预处理复杂度为O(nlog n)
然后查询,如何从d里面O(1)地查到任意区间[L, R]的最小值呢?
实际上,我们也可以像上面递推一样,分成两个部分,但是由于区间长度n = R-L+1不一定是2的幂,所以可能不能恰好分成两部分——但