RMQ—ST表
RMQ(Range Minimum/Maximum Query),RMQ是一个求给定范围内最大最小值的问题。我们一般使用st算法来解决这类问题(Sparse Table)。这个算法原理不难,主要是各种边界条件容易错
比如一个数组num[1000],我们想求num[x]~num[y]之间所有数的最大或最小值,如果只有一对x,y显然这个问题很好解决,但如果多对x,y或者任意一段长度内的最大最小值就不是那么好求了。
st算法是一个动态规划又有点类似二分的算法,通过维护一个二维数组st[i][j],st[i][j]代表的是num[i]~num[i+2^j-1]这段子数组之间的所有数的最大或最小,为什么是i+2^j-1?这是为了保证这个子数组一共有2^j个数,自己简单推一下就知道了。
我们发现st[i][0]就是num[i]~num[i+2^0-1]间的最大最小值,显然就只能是num[i],这样我们就能初始化st[i][0],而剩下的我们通过状态转移方程:
st[i][j] = min/max( st[i][j-1], st[i+(1<<(j-1))][j-1] )得到 ,<<是位运算,相当于得到2^(j-1)这个数,这个状态转移方程基本上就是二分,num[i]~num[i+2^j-1] 可以分成两个子数组num[i]~num[i+2^(j-1)-1] 和 num[i+2^(j-1)]~num[i+2^j-1](这也是为什么st要定义成2的次方形式,就是为了方便二分),两个子数组都有2^(j-1)个数
根据st的定义,稍微推算一下就可以得出状态转移方程,由于我们第一步推了st[i][0]的所有值,而状态方程都有[j-1]这个形式,所以构建整个st数组可以通过两重循环,j在外i在内,从j=1开始(j-1=0)。
这些都好理解,蛋疼的是边界的确定,一定要理解你写的边界究竟是数组形式(0~n-1)还是从1~n的形式
void RMQinit( int lhs, int rhs )
{
for( int i = lhs; i < rhs; i++ )
st[i][] = num[i]; for( int j = ; lhs + (<<j) - < rhs; j++ )
for( int i = lhs; i + (<<j) - < rhs; i++ )
st[i][j] = min( st[i][j-], st[i + (<<(j-))][j-] );
}
光求了st数组还不够,比如我们要找num[600]~num[999]之间的最大最小,而st都是以2的 次方形式给出,999-600+1= 400,400又是2的几次方呢?
所以我们寻找与400最接近但又不大于400的2的次方数,即256(这样能保证600~999这段区间一定会被覆盖完全),这样分别寻找600~600+256,和999-256+1~999间最大最小,再在这两个值中取最大最小。
int find( int lhs, int rhs )
{
int k = (int)(log10((rhs-lhs+))/log10(2.0));
return min( st[lhs][k], st[rhs-(<<k)+][k] );
}
比如这段代码,如果输入find(600,999)k就是400取以2为底的对数,取整后就应该是8,2^8就是256,这样st[lhs][k]就是600~600+2^8,st[rhs-(1<<k)+1][k]就是999-2^8+1-999
RMQ—ST表的更多相关文章
- RMQ——ST表
ST表 ST表是一种解决RMQ问题的强有力工具, 可以做到O(nlogn)预处理,O(1)查询. st[i][j] 表示区间 [i, i + 2 ^ j - 1] 的最大值. 初值 st[i][0] ...
- hdu6356 Glad You Came 杭电多校第五场 RMQ ST表(模板)
Glad You Came Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)
题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...
- RMQ问题 - ST表的简单应用
2017-08-26 22:25:57 writer:pprp 题意很简单,给你一串数字,问你给定区间中最大值减去给定区间中的最小值是多少? 用ST表即可实现 一开始无脑套模板,找了最大值,找了最小值 ...
- 算法学习 - ST表 - 稀疏表 - 解决RMQ问题
2017-08-26 21:44:45 writer:pprp RMQ问题就是区间最大最小值查询问题: 这个SparseTable算法构造一个表,F[i][j] 表示 区间[i, i + 2 ^ j ...
- POJ 3264 Balanced Lineup 【ST表 静态RMQ】
传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total S ...
- [poj3264]rmq算法学习(ST表)
解题关键:rmq模板题,可以用st表,亦可用线段树等数据结构 log10和log2都可,这里用到了对数的换底公式 类似于区间dp,用到了倍增的思想 $F[i][j] = \min (F[i][j - ...
- 【模板】RMQ问题的ST表实现
$RMQ$问题:给定一个长度为$N$的区间,$M$个询问,每次询问$[L_i,R_i]$这段区间元素的最大值/最小值. $RMQ$的高级写法一般有两种,即为线段树和$ST$表. 本文主要讲解一下$ST ...
- Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树
思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用 lazy=0 没被覆盖过 els ...
随机推荐
- C++自己用模板减少工作量
今天写代码,遇到这样一个类似如下的需求: auto componentClassSavedByPLC = std::make_shared<ComponentClassSavedByPLC> ...
- spring:常用的注解
bean.xml中配置依赖 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- git sync tags with remote
git 同步遠程標籤 在 .git/config的 [remote "origin"] 下加了 fetch = +refs/tags/*:refs/tags/* 最後就變成 [re ...
- 解决element 分页组件,搜索过后current-page 绑定的数据变了,但是页面当前页码并没有变的问题
前言上一篇写前台解决分页问题的时候没有这个问题,但是在实际项目后台中有遇到过,所以在这里专门说一下,如果参考前台分页出现这种问题了,也可以使用这种方法!bug:vue和element实现的后台分页,当 ...
- sqlite3-入门日记4-实现C++类封装
一.前言: 今天试了下如何用C++类实现接口封装,感觉蛮好 .用于封装的类主要有两个,SQLiteStatement类和SQLiteWrapper类,是一个老外写的.我看了下源码,主要是对C接口进 ...
- (转)剖析Linux文件编码的查看及修改
Linux文件编码的查看和修改都有不止一种做法,如果你需要在Linux中操作windows下的文件,那么很可能会经常遇到文件编码转换的问题,如何进行这项工作,也应该是经常工作在双系统下的操作者的必须掌 ...
- 服务器迁移部署PosWeb
绑定 基本配置 高级配置
- hibernate 映射总结
单向一对多实体配置:在一的实体中设置多的一方SET集合配置文件:在一的一方用set 设置 one to many表配置:多方表的外键指向一方表的主键; 双向一对多实体配置:在一的实体中设置多的一方SE ...
- Tree and Permutation (HDU 6446) 题解
// 昨天打了一场网络赛,表现特别不好,当然题目难度确实影响了发挥,但还是说明自己太菜了,以后还要多多刷题. 2018 CCPC 网络赛 I - Tree and Permutation 简单说明一下 ...
- 关于Spring Cloud Feign的一些记录!
学习Spring Cloud Feign过程中,相关资料都会反复强调:微服务调用的话(@FeignClient) 客户端方法的返回值和服务端方法的返回值还有方法名之类的都是要求一致的! 关于方法名是 ...