RMQ问题原理及实现

写在前面

        首先我们要明白RMQ表示的是什么:Range Minimum/Maximum Query(区间最小值/区间最大值),这里我们主要介绍的一种算法是ST算法,他预处理的复杂度为O(nlogn),查询复杂度为O(1),主要基于的思想就是动态规划。

RMQ问题算法详解

        我们知道这个算法是基于动态规划来进行的,我们就要首先说一下状态转移方程,我们定义:

dp[i][j]:从位置i开始,长度为(2^j)中最小或者最大的数是什么,我们这里就先讨论最小值的算法,然后是我们的状态转移方程:

dp[i][j] = min(dp[i][j-1],dp[ i+(1<<(j-1)) ][j-1]);

他的意思就是将[ i , i + (1<状态转移方程。

    实现预处理

        我们知道当j = 0 时,表示长度为1时的最小值,那么也就是它本身,然后后面的再去更新dp内容

void init_RMQ(int n,int a[])
{
    for(int i=0;i

    查询操作

int RMQ(int L,int R,int a[])
{

    int k=0;
    while(1<<(k+1)<=R-L+1)   //我们要得到这个区间中的k的大小
        k++;//这里计算出需要2的几次方能够把这个范围包围起来,可能会有点小,所以就会有重复计算的部分,但是不会影响计算的速度,因为已经进行过预处理了!
    return min(dp[L][k],dp[R-(1<

那么我们就得到了我们最终的程序

#include 
#include 
#include 
#include 

using namespace std;
typedef long long ll;
const int MAXN = 1100;
int dp[MAXN][MAXN];     //d[i][j]:第i个数起,向后连续2^j个数中的最大值

///RMQ算法用于计算区间最小值,当然也能改成最大值!
void init_RMQ(int n,int a[])
{
    for(int i=0;i
如果有错误,欢迎大家在下面评论区评论,谢谢!

       

你可能感兴趣的:(后缀数组)