ST(稀疏表)算法


一、ST算法(Sparse Table):

  • ST(Sparse Table,稀疏表)算法是求解RMQ问题的经典在线算法,以O(nlogn)时间预处理,然后在O(1)时间内回答每个查询。ST算法本质上是动态规划算法,定义了一个二维辅助数组st[n][n],st[i][j]表示原数组a中从下标i开始,长度为2^j的子数组中的最值(以最小值为例)。
  • 预处理:要求解st[i][j]时,即求下标i开始,长度为2^j的子数组的最小值时,可以把这段子数组再划分成两半,每半的长度为2^(j-1),于是前一半的最小值为st[i][j-1],后一半的最小值为st[i+2^(j-1)][j-1],于是动态规划的转移方程为:st[i][j] = min(st[i][j-1], st[i+2^(j-1)][j-1])长度为2^j的情况只和长度为2^(j-1)的情况有关,只需要初始化长度为2^0=1的情况即可。而长度为1时的最小值是显然的(为其本身)。
  • 查询: 现在问题是,st数组可以怎样加速我们的查询呢?这也是算法的巧妙之处,假设求下标在u到v之间的最小值。先求u和v之间的长度len=v-u+1,然后求k=ln(len),则u到v之间的子数组可以分为两部分: 以u开始,长度为2^k的一段 以v结束,长度为2^k的一段(可以计算得到起始位置为v-2^k+1)注意,一般情况下这两段是重叠的,但是这两段的最小值中较小的一个仍然是u到v的最小值。于是RMQ(u,v) = min(st[u][k], st[v-2^k+1][k])
  • 原文链接:http://noalgo.info/489.html

二、关键代码:

  • 预处理:
    void Init(){
    	for(int i = 0; i < MaxSize; ++i) ST[i][0] = Source[i];
    	for(int j = 1; (1<<j) <= MaxSize; ++j)
    		for(int i = 0; i + (1<<j) - 1 < MaxSize; ++i)
    			ST[i][j] = max(ST[i][j-1],ST[i + (1<<(j-1))][j-1]);
       }

  • 查询:
        int ln(int x){//对数函数 向下取整
            float fx;
            unsigned long ix, exp;
    
            fx = (float)x;
            ix = *(unsigned long*)&fx;
            exp = (ix >> 23) & 0xFF;
    
            return exp - 127;
        }
    
        int RMQ(int l,int r){
        	int len = r - l + 1;
        	int k = ln(len);
        	return max(ST[l][k],ST[l+(r - (<span id="transmark"></span>1<<k) + 1][k]);
        }


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值