关闭

st表

标签: 数据结构st表
359人阅读 评论(0) 收藏 举报
分类:

st表是用来查询数组中区间最值的。它应用的是动态规划的方法。

首先给一个数组a[0....n-1],长度为n,下标从0开始。现在要求区间[L,R]的最小值。

需要预处理出一个二维数组st[ i ] [ j ] ,它表示从下标i开始连续2^j个数中的最小值。边界条件为st[ i ] [ 0 ] = a[ i ],相当于从a[ i ] 开始的2^0 = 1个数的最小值,也就是a[ i ]。

动态规划的状态转移方程为:st[ i ][ j ] = min( st[ i ][ j - 1 ] , st[ i + 2^( j-1 )][ j - 1 ] )。

怎么理解这个转移方程?

现在的区间为[ i , i + 2^j -1 ] ,区间长度为 len  = 2^j。现在把这个区间分为两个等长区间1 : [ i , i + 2^(j - 1) - 1],区间长度为2^(j-1),区间2: [ i + 2^(j - 1) ,i + 2^j - 1],区间长度为2^j - 2^(j-1) = 2^(j-1)。这两个区间的最小值分别是st[ i ][ j - 1 ] ,st[ i + 2^(j-1) , j -1 ],也就是转移方程。

遍历的时候让i从n-1到0。


查询的时候,对于区间[L , R],k = floor(log2(L-R+1)),
将区间分解为两个长度为2^k的区间求最小值就行了。一个是从左边开始长度为2^k
,一个是从右边开始往左长度为2^k,显然这两个区间可以覆盖区间[L , R]。



源代码:

 

/*
st表:给一个数组A[n],动态查询区间[L,R]的最值
*/

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;

const int maxn = 1e5;
int stTable[maxn][32];
int preLog2[maxn];

void st_prepare(int n,int *array){
  preLog2[1] = 0;
  for(int i = 2; i <= n; i++){
    preLog2[i] = preLog2[i-1];
    if( (1 << (preLog2[i]+1) ) == i)
    ++preLog2[i];
  }

  for(int i = n-1; i >= 0; i--){
    stTable[i][0] = array[i];
    for(int j = 1; (i+(1<<j) - 1) < n; j++)
    stTable[i][j] = min(stTable[ i ][ j-1 ],stTable[ i + 1<<(j-1) ][ j-1 ]);
  }
}

int query(int l,int r){
  int len = r - l + 1, k =preLog2[len];
  return min(stTable[l][k],stTable[r-(1<<k) + 1][k]);
}

int main(){
  int n = 10;
  int a[10] = {1,2,3,4,5,6,7,8,9,10};
  st_prepare(n,a);
  int l,r;
  while(cin>>l>>r){
    if(l==0 || r == 0)break;
    cout<<query(l-1,r-1)<<endl;
  }
  return 0;
}






0
0
查看评论

ST表算法详解

ST表算法详解(算是吧)ST表就是一个用来解决rmq(区间最值)问题的算法。 ST表不支持在线修改。 预处理时间复杂度O(nlogn),查询时间O(1)。 ST表算法详解(求最小值): 用mn[i][j]表示从j到j+2^i-1的最小值(长度显然为2^i)。 任意一段的最小值显然等于min...
  • Hanks_o
  • Hanks_o
  • 2017-08-25 08:21
  • 552

ST表

风满山楼,执吾之剑,破万重天!
  • WhiStLenA
  • WhiStLenA
  • 2016-08-12 14:38
  • 6544

RMQ--ST表算法理解

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j ST算法(Sparse Table),ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nl...
  • qq1169091731
  • qq1169091731
  • 2016-07-21 11:59
  • 1349

LCA(最近公共祖先算法)之在线st表法

第一篇博文,练练手,做个笔记,呵呵。 有关于LCA问题不再赘述,简而言之就是树上两点的最近祖先节点。使用st表方法建表效率O(nlogn),查询基本上是O(1),而且应用灵活,可一边读入一边输出,而且比lca的tarjan算法好写很多。 先贴个代码,具体解释之后再填坑。 #include #in...
  • henryn111
  • henryn111
  • 2016-08-22 23:02
  • 362

求解区间最值的ST算法

作用:ST算法是用来求解给定区间RMQ的最值,本文以最小值为例 举例: 给出一数组A[0~5] = {5,4,6,10,1,12},则区间[2,5]之间的最值为1。 方法:ST算法分成两部分:离线预处理 (nlogn)和 在线查询(O(1))。虽然还可以使用线段树、树状链表等求解区间最值,但是ST算...
  • insistGoGo
  • insistGoGo
  • 2013-08-12 18:24
  • 4815

st表求区间最大值

Input 第一行给出一个数字N,接下来N+1行,每行给出一个数字Ai,(0 接来给出一个数字Q(Q 每组询问格式为a,b即询问从输入的第a个数到第b个数,其中的最大值是多少 Output 如题所述 Sample Input 10 0 1 2 3 2 3 4 3 2...
  • qq_39696474
  • qq_39696474
  • 2017-08-21 15:33
  • 138

BZOJ 1047 [HAOI2007]理想的正方形 二维ST表+压维

Description   有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值 的差最小。 Input   第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每 行相邻两数之间用一空格分隔...
  • ThinFatty
  • ThinFatty
  • 2017-07-02 22:28
  • 339

[2017纪中10-24]方阵 二维ST表

题面 假的数据。。。考场上被坑成0分。 首先两个log的二维ST表很好想,st[i][j][k][l]表示以点(i,j)向右2^k,向下2^l的矩形内的答案。 (假设)考虑真的长不超过宽的两倍,我们可以把它分成两个以宽为边长的正方形(当然可能会有部分重叠),那么询问都转化成正方形,只需要预处理...
  • DOFYPXY
  • DOFYPXY
  • 2017-10-24 16:20
  • 148

Sparse Table ST表

ST表(Sparse Table)是能够区间查询最值的数据结构,它采用倍增与dp的思想进行维护。 ST表复杂度:空间复杂度O(nlogn),预处理时间复杂度O(nlogn),查询时间复杂度O(1)。
  • Kanosword
  • Kanosword
  • 2016-09-25 12:02
  • 586

【RMQ算法】ST表

转自:http://blog.csdn.net/liang5630/article/details/7917702 初学RMQ,这个讲解易懂,收藏! 1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问...
  • jchangbrave
  • jchangbrave
  • 2016-09-04 11:53
  • 155
    个人资料
    • 访问:45221次
    • 积分:1113
    • 等级:
    • 排名:千里之外
    • 原创:68篇
    • 转载:1篇
    • 译文:2篇
    • 评论:2条
    最新评论