RMQ问题的ST算法

转载 2012年03月22日 20:21:31

来源:http://www.cnblogs.com/ljsspace/archive/2011/08/04/2127317.html

他博客里好多在线算法,本篇是计算O(1)时间查询无序数组某段的最小值。

ST(Sparse Table)算法的基本思想是,预先计算从起点A[i]开始长度为2的j次方(j=0,1...logn)的区间的最小值,然后在查询时将任何一个区间A[i..j]划分为两个预处理好的可能重叠的区间,取这两个重叠区间的最小值。

在预处理阶段,从起点A[i]开始,任何一个长度为2^j的区间都可以划分为两个长度2^(j-1)的区间,其中第一个区间的范围为:i...i+2^(j-1)-1;第二个区间的范围为:i+2^(j-1)...i+2^j-1。用M[i,j]表示从A[i]开始,长度为2^j的区间(即A[i]...A[i+2^j-1])最小值对应的下标,那么A[M[i,j]] = min{A[i...i+2^(j-1)-1], A[i+2^(j-1)...i+2^j-1]}。  利用DP思想,先计算M[i,j-1]的值,然后计算M[i,j]的值。

在查询阶段,任何区间A[i..j]的长度d=j-i+1,令k=floor(logd),那么该区间可以被两个长度为2^k的子区间完全覆盖,这两个长度为2^k的区间可以有重叠。由于这两个区间已经在预处理中求得最小值,因此可以取二者的最小值得到A[i..j]的最小值。

ST算法预处理阶段的复杂度为O(nlogn),查询阶段的复杂度为O(1)。

实现:

/**
 *
 * Using ST(Sparse Table) algorithm to solve RMQ problem
 * time complexity: <O(nlogn),O(1)>
 *
 
 * Copyright (c) 2011 ljs (http://blog.csdn.net/ljsspace/)
 *
 * @author ljs
 * 2011-08-02
 *
 */
public class RMQ_ST {
     
    //ST: O(nlogn) for preprocessing
    public int[][] preprocess(int[] A){
        int n = A.length;
        //floor value
        int maxJ=(int)(Math.log(n)/Math.log(2));
         
        int[][] M = new int[n][maxJ+1];
         
        //initial condition for dynamic programming: the RMQ for interval length=1
        for (int i = 0; i < n; i++)
              M[i][0] = i;
         
        //dynamic programming: compute values from smaller(j=1) to bigger intervals
        for (int j = 1; j<=maxJ; j++){
            for (int i = 0; i + (1 << j) - 1 < n; i++){
                int nexti = i + (1 << (j - 1));
                if (A[M[i][j - 1]] <= A[M[nexti][j - 1]])
                    M[i][j] = M[i][j - 1];
                else
                    M[i][j] = M[nexti][j - 1];
            }
        }
        return M;
    }
     
    //ST: O(1) for querying
    public int query(int[] A,int[][] M,int i,int j){
        if(j<i){
            //swap i and j
            int tmp=i;i=j;j=tmp;
        }
        int k = (int)(Math.log(j-i+1)/Math.log(2));
        //the first interval
        int mina = M[i][k];
        int minb = M[j-(1<<k)+1][k];
        if(A[mina]<=A[minb])
            return mina;
        else
            return minb;
    }
 
    public static void main(String[] args) {       
        int[] A=new int[]{0,1,2,3,7,1,9,2,8,6};
        RMQ_ST st = new RMQ_ST();
        int[][] M = st.preprocess(A);
         
         
        System.out.format("%n***********************%n");      
        int i=3,j=7;       
        int min = st.query(A,M, i,j);
        System.out.format("RMQ for A[%d..%d]: A[%d]=%d", i,j,min,A[min]);
         
        System.out.format("%n***********************%n");
        j=3;i=7;   
        min = st.query(A,M, i,j);
        System.out.format("RMQ for A[%d..%d]: A[%d]=%d", i,j,min,A[min]);
         
        System.out.format("%n***********************%n");
        for(int x=0;x<A.length;x++){
            for(int y=0;y<x;y++){
                System.out.format("    ");
            }
            for(int y=x;y<A.length;y++){
                int p = st.query(A,M,x,y);             
                System.out.format(" %d/%d",A[p],p);
            }
            System.out.println();
        }  
    }
 
}

HDU3183(RMQ问题,ST算法)

题目:A Magic Lamp   题意: 对于一个序列A[1...N],一共N个数,除去M个数使剩下的数组成的整数最小。 也就是说在A[1...N]中顺次选取N-M个数,使值最小。 本题很有技巧...
  • ACdreamers
  • ACdreamers
  • 2013年03月19日 16:29
  • 2954

理解RMQ问题和ST算法的原理

1.RMQ问题     RMQ (Range Minimum/Maximum Query):对于长度为n的数组A,回答若干询问RMQ(A,i,j)(i,jRMQ问题是指求区间最值的问题。最简单的方法...
  • aitangyong
  • aitangyong
  • 2014年05月25日 13:16
  • 1140

RMQ--ST表算法理解

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j ST算法(Sparse Tabl...
  • qq1169091731
  • qq1169091731
  • 2016年07月21日 11:59
  • 1087

RMQ(st在线算法模板)

#include #include #include using namespace std; #define M 100010 #define MAXN 500 #define MAXM 500 ...
  • mengxingyuanlove
  • mengxingyuanlove
  • 2015年08月18日 21:13
  • 647

针对RMQ问题的ST算法

RMQ问题,即求区间最大最小值的问题:对于长度为N的数列,询问若干次RMQ(A,I,J)(I   我们可以采取朴素的直接搜的算法,如果数据非常大的话,直接搜就会爆时间爆的很惨。然后我们可以采取二...
  • fqh1379
  • fqh1379
  • 2015年02月08日 08:43
  • 319

RMQ问题之ST算法

原文:http://blog.csdn.net/sdj222555/article/details/7875575 ST算法的基本原理百度一下就可以知道   RMQ(Ran...
  • witnessai1
  • witnessai1
  • 2017年03月21日 23:21
  • 101

RMQ问题ST算法

/* RMQ(Range Minimum/Maximum Query)问题: RMQ问题是求给定区间中的最值问题。当然,最简单的算法是O(n)的,但是对于查询次数很多(设置多大100万次),O(...
  • lgh1992314
  • lgh1992314
  • 2013年05月31日 14:15
  • 784

RMQ问题之ST算法

ST算法的基本原理百度一下就可以知道   RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。可以写一个线段树,但是预处理和查询的复杂度都是O(logn)。这里...
  • ascvsderf
  • ascvsderf
  • 2016年04月25日 09:35
  • 138

RMQ问题的ST算法

1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j当然,该问题也可以用...
  • wyg1997
  • wyg1997
  • 2016年04月27日 07:12
  • 208

RMQ问题之ST算法

转自 点击打开链接 ST算法的基本原理百度一下就可以知道   RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。可以写一个线段树,但是预处理和查询的...
  • qq_16843991
  • qq_16843991
  • 2014年12月16日 16:11
  • 300
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:RMQ问题的ST算法
举报原因:
原因补充:

(最多只允许输入30个字)