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 ...
随机推荐
- Java A*算法搜索无向图最短路径
网上看了很多别人写的A*算法,都是针对栅格数据进行处理,每次向外扩展都是直接八方向或者四方向,这样利于理解.每次移动当前点,gCost也可以直接设置成横向10斜向14. 但是当我想处理一个连续的数据集 ...
- Neo4j-Apoc
Neo4j-Apoc APOC https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_virtual_nodes_rels 提供的函数 存储过 ...
- 廖雪峰Java15JDBC编程-1关系数据库基础-1关系数据库简介
1.数据库 1.1 定义 数据库是按照数据结构来组合.存储和管理数据的软件. 1.2 数据库模型 数据库有层次模型.网状模型.关系模型三种模型. 2 关系数据库 关系数据库是建立在关系模型上的数据库, ...
- 廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService
Java语言内置多线程支持: 创建线程需要操作系统资源(线程资源,栈空间) 频繁创建和销毁线程需要消耗大量时间 如果可以复用一个线程 线程池: 线程池维护若干个线程,处于等待状态 如果有新任务,就分配 ...
- Python3基础笔记_迭代器
# Python3 迭代器与生成器 import sys ''' 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开 ...
- ThinkPHP 读取数据
在ThinkPHP中读取数据的方式很多,通常分为读取数据.读取数据集和读取字段值. 步进电机和伺服电机 数据查询方法支持的连贯操作方法有: 连贯操作 作用 支持的参数类型 where 用于查询或者更新 ...
- csp-s模拟测试55 联,赛,题题解
题面:https://www.cnblogs.com/Juve/articles/11610969.html 联: 用线段树维护区间和,要修改成1或0就线段树修改区间和 如果是异或,那么新的区间和就是 ...
- 平衡树模板【splay的实现】
[平衡树splay实现] 无注释代码 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=1e ...
- VS2010-MFC(对话框:非模态对话框的创建及显示)
转自:http://www.jizhuomi.com/software/162.html 前面已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换.本节会将上一讲中 ...
- Python数据挖掘之决策树DTC数据分析及鸢尾数据集分析
Python数据挖掘之决策树DTC数据分析及鸢尾数据集分析 今天主要讲述的内容是关于决策树的知识,主要包括以下内容:1.分类及决策树算法介绍2.鸢尾花卉数据集介绍3.决策树实现鸢尾数据集分析.希望这篇 ...