RMQ问题 ST_table 实现

void RMQ_init(int l, int r)
{
    int i, j;
    for (i = l; i <= r; ++i)
        dp[i][0] = a[i];
    for (j = 1; l + (1 << j) - 1 <= r; ++j)
    {
        for (i = l; i + (1 << j) - 1 <= r; ++i)
        {
            dp[i][j] = max<int>(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int ST(int l, int r)
{
    int k = log2(r - l + 1);
    return max<int>(dp[l][k], dp[r - (1 << k) + 1][k]);
}

RMQ_init()初始化,ST查询

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。

ST算法(Sparse Table),ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。

以求最小值为例,设dp [ i, j ]表示[ i, i+2^j-1]这个区间内的最大值,那么在询问到[a,b]区间的最小值时答案就是min(dp[a,k], dp[b-2^k+1,k]),其中 k 是满足2^k<=b-a+1(即长度)的最大的k,即k=[ln(b-a+1)/ln(2)]。

注释: [a, a+(1<<k)-1] ~[b-2^k+1,b-2^k+1+2^k-1 ]  得到b-2^k+1>=a (=>  k<=[ln(b-a+1)/ln(2)] )(当且取等号时k最大)(k取到最大,能保证覆盖待求最值的区间)
 

猜你喜欢

转载自blog.csdn.net/SuperBvs/article/details/84891137