RMQ

RMQ

  RMQ(Range Minimum/Maximum Query)是一种求区间内最大值或者最小值的算法,这里用st表来实现。

  st表首先就是需要倍增算法,以此来降低时间复杂度,那么就先来了解一下倍增算法。众所周知,任何数都能很容易地表示成二进制,倍增就是以2为底数,因此在二进制中表现良好,只需要进行一次位运算的左移就行了。

  我们先建立一个数组 s [ i ] [ j ] s[i][j] s[i][j],表示 a [ i ] 到 a [ i + 2 j − 1 ] a[i]到a[i+2^j-1] a[i]a[i+2j1]的最值,通过倍增的预处理先将表填满,之后就可以通过 O ( 1 ) O(1) O(1)的操作,直接得到所求值。(虽然在只求值一次的情况下还没有传统的遍历来的快)

  建表的过程其实就是dp,而每次的子问题就是 s [ i ] [ j ] 到 s [ i ] [ j − 1 ] s[i][j]到s[i][j-1] s[i][j]s[i][j1]之间的最值,毕竟作为质数,差1就是差一倍,这就是表示方便之处。以j为外层循环,i为内层循环,一层一层将表填满。

代码如下:

void RMQ(int n){
    for(int i=0;i<n;++i){
        s[i][0]=a[i];
    }
    for(int j=1;j<k;++j){
        for(int i=0;i<n;++i){
            if(i+(1<<j)-1<=n){
                s[i][j]=min(s[i][j-1],s[i+(1<<(j-1))-1][j]);
                //s[i][j]=max(s[i][j-1],s[i+(1<<(j-1))-1][j]);
            }
        }
    }
}

  st表已经建立好了,剩下的就是 O ( 1 ) O(1) O(1)的查询操作了。

int query(int a,int b){
    int tmp=int(log(b-a+1)/log(2));
    return s[a][tmp];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值