ST表(RMQ问题)

ST表能够O(1)地解决区间[l,r]之间最值问题

1.建表,首先明白ST[i][j],表示的是区间[i, i+(1<<j)-1]的最值,区间大小为2^j。首先初始化ST[i][0]=a[i]。

void init(){
    
    for(int i=1; i<=n; i++){
        ST[i][0]=a[i];
    }
}

因为ST[i][0]表示区间[i,i+(1<<0)-1],也就是[i,i],即a[i]本身。

然后建表,首先确定k=log2(区间大小),这么做的目的是确定最大的j以保证ST[i][i+(1<<j)-1]在指定的区间里面。

void build(int l, int r){
    int k = log2(r-l+1);
    init();
    for(int j=1; j<=k; j++)
        for(int i=1; i<=r-(1<<j)+1; i++){
            ST[i][j] = max(ST[i][j-1], ST[i+(1<<(j-1))][j-1]);//[i,i+(1<<j)-1]可以分为[i,i+(1<<(j-1))-1]和[i+(1<<(j-1))][j-1]两个区间大小为(1<<(j-1))的区间,运用倍增的思想赋值ST[i][j]
        }
}

可以通过下面的例子进一步理解:

下列有10个数,从序列1开始到10;第2行到第11行是ST存储的情况:注意行为j表示当前区间大小,列为i表示区间起始序号。便于理解现在改为i为行,列为j。

2.查询给定区间[l,r]的最值:

跟建表一样确定 k = log2(r-l+1), 然后从ST[l][k]和ST[r-(1<<k)+1][k], 表示的区间分别是[l,l+(1<<k)-1]和区间[r-(1<<k)+1][r]两个大小为(1<<k)的子区间,虽然两个区间可能有重复的部分但是不影响最后结果。

int find(int l, int r){
    int k = log2(r-l+1);
    return max(ST[l][k], ST[r-(1<<k)+1][k]); 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值