ST算法求解RMQ问题(区间最值)

效率:O(n log n)预处理,O(1)询问

思想:

用 f [ i ][ j ] 表示 以i 开头的区间,包括2^j 个元素的一段区间的最值

那么有初始化的初始化 f [ i ][ 0 ] = a[ i ] (a[ I ]表示第I个元素的值)

然后就有两种初始化的方法

1) 选择一个位置为更新点,然后枚举 2 ^ j ,即固定I ,求 f [ const I ][ j ]

2) 每次选择一个区间长度,然后枚举位置,即固定 j ,求 f [ I ][ const j ]

那么哪一种效率更高呢?

如果选择方案1,那么显然没有办法优化

那么只能是方案2了。

由于这都是求2 ^ j (j为整数)的区间的长度,那么就可以直接由这个区间拆成的两个1 / 2长度的区间来求,令人欣慰的是,这一段区间在上一个步骤一定已经求过了。这样每一次计算都很容易,并且计算的次数是递减的。砖家证明,全部效率O(n log n)(因为初始化的初始化是在读数时就完成的,不计入)

下面贴出代码~~~

用的是二维vector~~~

# include <iostream>

# include <fstream>

# include <cstdio>

# include <cstdlib>

# include <cstring>

# include <cmath>

# include <algorithm>

# include <vector>

# include <deque>

# include <list>

# include <map>

using namespace std ;

int n , temp ;

vector <vector <int> > f ;

void init () ;

void st () ;

void ask () ;

int main ()

{

freopen ( "st.in"  , "r" , stdin  ) ;

freopen ( "st.out" , "w" , stdout ) ;

init () ;

st () ;

ask () ;

}

void init ()

{

vector <int> te ;

cin >> n ;

temp = log ( n ) / log ( 2 ) ;

for ( int i = 0 ; i <= n ; i ++ )

{

te.clear () ;

for ( int j = 0 ; j <= temp ; j ++ )

{

te.push_back ( 0 ) ;

}

f.push_back ( te ) ;

}

for ( int i = 1 ; i <= n ; i ++ )

{

cin >> temp ;

f[ i ][ 0 ] = temp ;

}

cout << f.size () << '\n' << te.size () << '\n' ;

for ( int i = 0 ; i < f.size () ; i ++ )

for ( int j = 0 ; j < te.size () ; j ++ )

{

cout << i << ' ' << j << " : " << f[ i ][ j ] << '\n' ;

}

}

void st ()

{

int kkk ;

for ( int j = 1 ; j <= temp ; j ++ )//1<<j要+括号,位运算的级别貌似不怎么高

for ( int i = 1 ; i <= n - ( 1 << j ) + 1 ; i ++ ) //注意下面这里的是 i + 1 << ( j - 1 )最后没有-1

//因为比如求f[ 1 ][ 2 ]时,f[ 1 ][ 1 ] : 1 ~ 2 , 下一个应该是 f[ 3 ][ 1 ],正好+上一个一半的长度

f[ i ][ j ] = max ( f[ i ][ j - 1 ] , f[ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ) ;

}

void ask ()

{

int q , l , r , maxn = 0 ;

cin >> q ;

for ( int i = 1 ; i <= q ; i ++ )

{

cin >> l >> r ;

temp = ( int )log ( r - l ) / log ( 2 ) ;//不要加 1,否则可能超出这个区间

maxn = max ( f[ l ][ temp ] , f[ r - ( 1 << temp ) + 1 ][ temp ] ) ;

cout << maxn << '\n' ;

}

}

调试这个代码费了我一下午!所以说一定要记住:位运算的左移(<<)和右移(>>)的级别特别低~!~~!!!甚至低于+-!

转载于:https://www.cnblogs.com/Stery/archive/2012/08/06/2625587.html

RMQ的ST算法(区间最值)相关推荐

  1. 动态规划-RMQ问题(ST算法)

    文章目录 RMQ问题 ST算法 模板 例题 P2251 质量检测 P1816 忠诚 P2216 [HAOI2007]理想的正方形 RMQ问题 RMQ(Range Minimum/Maximum Que ...

  2. ST算法 - RMQ(区间最值问题)—— 倍增

    文章目录 引入倍增: 例题1:区间和 例题2:Genius ACM 应用: ST算法 求解 RMQ(区间最值问题) 模板Code: 练习题: ST算法 维护区间最大公约数 例题:Pair of Num ...

  3. 1470: 区间求最值(RMQ问题,ST算法模板)

    1470: 区间求最值 Time Limit: 1 Sec Memory Limit: 128 MB [Submit][Status][Web Board] Description 给定一个长度为N ...

  4. RMQ问题-ST表倍增处理静态区间最值

    简介 ST表是利用倍增思想处理RMQ问题(区间最值问题)的一种工具. 它能够做到O(nlogn)预处理,O(1)查询的时间复杂度,效率相当不错. 算法 1.预处理 ST表利用倍增的思想.以洛谷的P38 ...

  5. RMQ算法,求区间最值

    poj 3264 Balanced Lineup@ 2016-07-27 11:15 49人阅读 评论(0) 收藏 举报  分类: RMQ(Range MinimumMaximum Quer)(4)  ...

  6. RMQ问题(线段树算法,ST算法优化)

    RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值 ...

  7. RMQ ST算法简介

    RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就 ...

  8. RMQ问题,加深对ST算法的理解(Sparse Table)

    Sparse Table(稀疏表):简称ST 简介 ST 算法本质是动态规划. 时间复杂度为: 预处理:O(nlogn) 查询:O(1) 它 适宜用于 数据不再作出变化(也称离线) 的 区间最值 查询 ...

  9. ST算法解决RMQ问题

    关于ST算法,实际上它本身并不难,它的思想是动态规划.主要用来求RMQ问题,时间复杂度为O(NlgN+M)  关于RMQ问题描述: 输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数 ...

最新文章

  1. shiro系列二、身份验证和授权
  2. boost::intrusive::list_base_hook用法的测试程序
  3. 学科分类号4个空都填什么_高中英语完形填空的5个解题小技巧,大家都在用
  4. VLAN基础配置及Access接口
  5. Android底部导航栏实现(一)之BottomNavigationBar
  6. 交换两个变量的值,不使用第三个变量的四种方法
  7. UVA10474 Where is the Marble?【排序】
  8. 《架构漫谈》阅读感想
  9. Redmine管理项目1-自定义属性
  10. displayTag使用详解
  11. gif动态图批量加水印方法
  12. Nginx反向代理的配置
  13. python 运行画图时,报错:“RuntimeError: Invalid DISPLAY variable“
  14. NVME Reset
  15. 企业项目实战k8s篇(二十)持续集成与持续交付
  16. P1196 [NOI2002] 银河英雄传说 (并查集 合并
  17. Frida出现process with pid XXXX either refused to load frida-agent, or terminated during injection错误的原因
  18. 2016年8月18日 星期四 --出埃及记 Exodus 16:19
  19. c语言书本答案揭安全,c语言书本练习答案.docx
  20. Teamcity的安装及使用

热门文章

  1. 【GBS】How to communicate with technical professionals at basic level
  2. 国内著名IT公司(百度、搜狗、网易、新浪)2012校园招聘笔试、面试小结
  3. CentOS8.4 Samba服务配置
  4. 卡尔曼滤波——迭代过程
  5. Python Seaborn或者Matplotlib作图:改变x、y轴标签的字体大小(xlabel,ylabel)
  6. 陕西单招院校计算机专业排行,关于陕西高职院校的排名
  7. 无限循环:while True+if...break(打破循环) 用法
  8. Qt QTranslator多语言翻译例子
  9. Mysql更改字段位置
  10. Linux中光驱设备如何使用,如何在Linux操作系统下使用虚拟光驱