RMQ的ST算法(区间最值)
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算法(区间最值)相关推荐
- 动态规划-RMQ问题(ST算法)
文章目录 RMQ问题 ST算法 模板 例题 P2251 质量检测 P1816 忠诚 P2216 [HAOI2007]理想的正方形 RMQ问题 RMQ(Range Minimum/Maximum Que ...
- ST算法 - RMQ(区间最值问题)—— 倍增
文章目录 引入倍增: 例题1:区间和 例题2:Genius ACM 应用: ST算法 求解 RMQ(区间最值问题) 模板Code: 练习题: ST算法 维护区间最大公约数 例题:Pair of Num ...
- 1470: 区间求最值(RMQ问题,ST算法模板)
1470: 区间求最值 Time Limit: 1 Sec Memory Limit: 128 MB [Submit][Status][Web Board] Description 给定一个长度为N ...
- RMQ问题-ST表倍增处理静态区间最值
简介 ST表是利用倍增思想处理RMQ问题(区间最值问题)的一种工具. 它能够做到O(nlogn)预处理,O(1)查询的时间复杂度,效率相当不错. 算法 1.预处理 ST表利用倍增的思想.以洛谷的P38 ...
- RMQ算法,求区间最值
poj 3264 Balanced Lineup@ 2016-07-27 11:15 49人阅读 评论(0) 收藏 举报 分类: RMQ(Range MinimumMaximum Quer)(4) ...
- RMQ问题(线段树算法,ST算法优化)
RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小(大)值 ...
- RMQ ST算法简介
RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就 ...
- RMQ问题,加深对ST算法的理解(Sparse Table)
Sparse Table(稀疏表):简称ST 简介 ST 算法本质是动态规划. 时间复杂度为: 预处理:O(nlogn) 查询:O(1) 它 适宜用于 数据不再作出变化(也称离线) 的 区间最值 查询 ...
- ST算法解决RMQ问题
关于ST算法,实际上它本身并不难,它的思想是动态规划.主要用来求RMQ问题,时间复杂度为O(NlgN+M) 关于RMQ问题描述: 输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数 ...
最新文章
- shiro系列二、身份验证和授权
- boost::intrusive::list_base_hook用法的测试程序
- 学科分类号4个空都填什么_高中英语完形填空的5个解题小技巧,大家都在用
- VLAN基础配置及Access接口
- Android底部导航栏实现(一)之BottomNavigationBar
- 交换两个变量的值,不使用第三个变量的四种方法
- UVA10474 Where is the Marble?【排序】
- 《架构漫谈》阅读感想
- Redmine管理项目1-自定义属性
- displayTag使用详解
- gif动态图批量加水印方法
- Nginx反向代理的配置
- python 运行画图时,报错:“RuntimeError: Invalid DISPLAY variable“
- NVME Reset
- 企业项目实战k8s篇(二十)持续集成与持续交付
- P1196 [NOI2002] 银河英雄传说 (并查集 合并
- Frida出现process with pid XXXX either refused to load frida-agent, or terminated during injection错误的原因
- 2016年8月18日 星期四 --出埃及记 Exodus 16:19
- c语言书本答案揭安全,c语言书本练习答案.docx
- Teamcity的安装及使用
热门文章
- 【GBS】How to communicate with technical professionals at basic level
- 国内著名IT公司(百度、搜狗、网易、新浪)2012校园招聘笔试、面试小结
- CentOS8.4 Samba服务配置
- 卡尔曼滤波——迭代过程
- Python Seaborn或者Matplotlib作图:改变x、y轴标签的字体大小(xlabel,ylabel)
- 陕西单招院校计算机专业排行,关于陕西高职院校的排名
- 无限循环:while True+if...break(打破循环) 用法
- Qt QTranslator多语言翻译例子
- Mysql更改字段位置
- Linux中光驱设备如何使用,如何在Linux操作系统下使用虚拟光驱