为了明天不爆零,我还是把RMQ学完吧。(虽然明天可能仍然会爆零)
好了现在鼓掌请本场嘉宾RMQ上场(啪啪啪啪啪啪)
百度小姐姐说它是指对于长度为n的数列·A,回答若干次询问RMQ(A,i,j)(i,j小于等于n),
返回数列中下标在i到j的最小(大)值。
st算法:实际上就是个动态规划
(1)、预处理:o(nlogn)
f [ i ][ j ] 表示从第i个数起到第2 ^ j 个数中的最大值
例如数列 3 2 4 5 6 8 1 2 9 7 f [1][ 2] = 5;f [1][3] = 8......
可以看出f [ i ][ 0 ] = a[ i ]
把 f [ i ][ j ]平均分成两份
so f[ i ][ j ] = max(f [ i ][ j - 1],f [ i + 2 ^ (j - 1)][ j - 1 ]
(2)、查询: O(1)
因为区间长度为j - i + 1,所以我们可以取看k = log2(j - i + 1),
则有RMQ(i,j) = max(f [ i , k ],f [ j - 2 ^ k + 1, k ])
然后贴代码
void st(int n){
for(int i = 1;i <= n;i++)
dp[ i ][ 0 ] = A[ i ];
for(int j = 1;2 ^ j <= n;j++)
for(int i = 1;i + 2 ^ j - 1 <= n;i++)
dp[ i ][ j ] = max(dp[ i ][ j - 1],dp[i + 2 ^ j - 1 + 1][j - 1]);
int rmq(int l,int r)
{
int k = 0;
while(2 ^ K + 1 <= r - l + 1) k++;
return min(dp[ l ][ k ],dp[r - 2 ^ k + 1][ k ]);
}
然后就没有然后了......
围观的大爷大妈们可以搬着小板凳离开了。
不要相信以上的所有文字,我发现我之前可能写错了