RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为html
n的数列A,回答若干次询问RMQ(i,j),返回数列A中下标在区间[i,j]中的最小/大值。算法
这个有不少算法:这里介绍一种比较高效的ST算法解决这个问题。ST(Sparse Table)算法能够spa
在O(nlogn)时间内进行预处理,而后在O(1)时间内回答每一个查询。code
令dp(i,j)表示从 i 开始的,长度为 2^j 的一段中元素的最小值,htm
便可以递推出dp(i,j)=min(dp(i,j-1),dp(i+2^(j-1) , j-1))。blog
代码:get
void ST(int n) { for (int i = 1; i <= n; i++) dp[i][0] = A[i]; for (int j = 1; (1 << j) <= n; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) { dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]); } } } int RMQ(int l, int r) { int k = 0; while ((1 << (k + 1)) <= r - l + 1) k++; return max(dp[l][k], dp[r - (1 << k) + 1][k]);//int k=(int)(log(double(R-L+1))/log(2.0));
}