ST算法详解+例题 O(1)查询区间最大最小值

本文详细介绍了ST算法解决RMQ问题,适用于区间最值查询,复杂度为O(nlogn)预处理,O(1)查询。内容包括算法适用范围、初始化、查询方法,并通过poj 3368和3264两道例题进行解析,展示如何应用ST算法解决实际问题。
摘要由CSDN通过智能技术生成

RMQ问题

RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。
主要方法及复杂度如下:
1、朴素(即搜索),O(n)-O(qn) online。
2、线段树,O(n)-O(qlogn) online。
3、ST(实质是动态规划),O(nlogn)-O(q) online。
ST算法(Sparse Table),以求最大值为例,设d[i,j]表示[i,i+2^j-1]这个区间内的最大值,那么在询问到[a,b]区间的最大值时答案就是max(d[a,k], d[b-2^k+1,k]),其中k是满足2^k<=b-a+1(即长度)的最大的k,即k=[ln(b-a+1)/ln(2)]。
d的求法可以用动态规划,d[i, j]=max(d[i, j-1],d[i+2^(j-1), j-1])。
4、RMQ标准算法:先规约成LCA(Lowest Common Ancestor),再规约成约束RMQ,O(n)-O(q) online。
首先根据原数列,建立笛卡尔树,从而将问题在线性时间内规约为LCA问题。LCA问题可以在线性时间内规约为约束RMQ,也就是数列中任意两个相邻的数的差都是+1或-1的RMQ问题。约束RMQ有O(n)-O(1)的在线解法,故整个算法的时间复杂度为O(n)-O(1)。 - 度娘

ST算法

适用范围

今天学习的是RMQ的ST算法,先说明一下它的适用范围
复杂度是O(nlogn)的建表和O(1)的查询,并且不适用于更新。
如果更新的话就用线段树了,因为ST是直接建表了。
ps.(1 << k ) = 2^k

初始化

以最大值为例,最小值的初始化过程相同。
首先设A是要求区间最值的数列,f[i, j],表示从第i个数起连续 ( 1 << j )个数起连续数中的最大值。
比如来个数列:

1 2 3 5 7 9 2 10 3 4

f[1, 0]表示从第1个数起,长度为(1<<0) = 1位数范围的最大值,为1;
f[1, 2]表示从第1个数起,长度为(1<<2) = 4位数范围的最大值,为5;
f[2, 0]…为2;
f[2, 2]…为3;
可以发现,f[i, 0] = A[i]。
接下来是状态转移方程:
将f[i, j]分成两段,从 i 到 i+(1<<(j - 1))-1为一段,i + (1<<(j-1))到 i + (1 << j) - 1为一段,求解这段的最大值就行了。
状态转移方程:

f[ i, j ] = max( f[ i ][ j - 1 ] , f[ i + (1<<(j - 1)) ] [j - 1] )

状态转移方程表示的意义:
数列A中,以第i个数开头,总共(1 << j)位的连续子集的最大值,为以i开头共(1<<(j-1))位的连续子集 和 以i+(1<<(j-1))开头共(1<<(j-1))位的连续子集中的最大值。
初始化代码:

void queryInit()
{
    ////////////////////////////
    for (int i = 1; i <= n; i++)
    {
        minPoint[i][0] = maxPoint[i][0] = ///;
    }
    ////////////////////////////
    for (int j = 1; (1 << j) <= n; j++)
    {
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
        {
            int p = (1 << (j - 1));
            minPoint[i][j] = Min(minPoint[i][j - 1], minPoint[i + p][j - 1
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值