区间最小值查询,RMQ,Sparse-Table算法

来源:互联网 发布:青丘狐花月的头饰淘宝 编辑:程序博客网 时间:2024/05/16 10:47

给一个N元数组A[0..N-1],设计一个数据结构,支持查询操作Query(L,R),计算min{A[L]...A[R]};RMQ问题可以做到O(n)的预处理,O(1)的查询复杂度;以下JAVA代码是O(nlogn)的预处理,O(1)的查询复杂度;

参考文献:《算法竞赛入门经典训练指南》P197,刘汝佳,陈锋

package ProgrammingContest;public class RMQProblem {private int LEN = 0;private int EXP = 0;private int[] A = null;private int[][] D = null;public RMQProblem(int[] a) {LEN = a.length;EXP = minExp(LEN);A = a;D = new int[a.length][EXP];for ( int i=0; i<A.length; i++ ) D[i][0] = A[i];for ( int j=1; j<=EXP; j++ ) {for ( int i=0; (i+(1<<j)-1)<LEN; i++ ) {D[i][j] = min(D[i][j-1],D[i+(1<<(j-1))][j-1]);}}}public int query(int L, int R) {int k = 0;while ( ( 1 << k ) <= (R-L+1) ) {k++;}k--;return min(D[L][k],D[R-(1<<k)+1][k]);}private int minExp(int x) {int exp  = 0;int test = 1;while ( test < x ) {test <<= 1;exp++;}return exp;}private int min(int x, int y) {return (x<y)?x:y;}/** * @param args */public static void main(String[] args) {int[] v = {0, 1, 2, 3, 4, 5};RMQProblem inst = new RMQProblem(v);for ( int i=0; i<v.length; i++) {int r = inst.query(i,v.length-1);System.out.println(r);}}}