为了明天不爆零,我还是把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 ]);

}

然后就没有然后了......

围观的大爷大妈们可以搬着小板凳离开了。

不要相信以上的所有文字,我发现我之前可能写错了