RMQ问题

RMQ(区间最值查询)问题有多种解法

ST表的主要功能就是处理RMQ问题。记录一个区间内的最大最小值,dp[i][j]表示,从i位置开始的2^j个数中的最大值。查询时将该区间分为两段,保证这两段覆盖查询范围即可

void init()
{
    for(int j=0;(1<<j)<=n;j++){
        for(int i=1;(i+(1<<j)-1)<=n;i++){
            if(j)  dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            else dp[i][j]=num[i];
        }
    }
}
int query(int a,int b)
{
    int k=log2(b-a+1);
    return max(dp[a][k],dp[b-(1<<k)+1][k]);
}

树状数组也可用于解决RMQ问题。相较于ST表,树状数组还可以对数字进行单点修改维护。树状数组的做法,用于RMQ问题可能并不是那么直观,需要对代码进行适当修改,可以把目标区间尝试进行分段。

int lowbit(int x)
{
    return x&(-x);
}
void add(int k,int v)
{
    while(k<=n){
        tree[k]+=v;
        k+=lowbit(k);
    }
}
int getmax(int a,int b)
{
    if(b>a){
        if(b-lowbit(b)>a) return max(tree[b],getmax(a,b-lowbit));
        else return max(num[y],getmax(a,b-1));
    }
    return num[a];
}

线段树,相较于树状数组还多了区间修改维护的功能,但是也更复杂。酌情选择。具体代码见关于树状数组和线段树的博客,稍微改一下就可以用

posted @ 2020-10-09 17:41  太山多桢  阅读(176)  评论(0)    收藏  举报