【模板】RMQ问题的ST表实现
$RMQ$问题:给定一个长度为$N$的区间,$M$个询问,每次询问$[L_i,R_i]$这段区间元素的最大值/最小值。
$RMQ$的高级写法一般有两种,即为线段树和$ST$表。
本文主要讲解一下$ST$表的写法。(以区间最大值为例)
$ST$表:一种利用$dp$思想求解区间最值的倍增算法。
定义:$f(i,j)$表示$[i,i+2^{j}-1]$这段长度为$2^{j}$的区间中的最大值。
预处理:$f(i,0)=a_i$。即$[i,i]$区间的最大值就是$a_i$。
状态转移:将$[i,j]$平均分成两段,一段为$[i,i+2^{j-1}-1]$,另一段为$[i+2^{j-1},i+2^{j}-1]$。
两段的长度均为$2^{j-1}$。$f(i,j)$的最大值即这两段的最大值中的最大值。
得到$f(i,j)=max\{f(i,j-1),f(i+2^{j-1},j-1)\}$。
void RMQ(int N){
/*注意外部循环从j开始,
因为初始状态为f[i][0],
以i为外层会有一些状态遍历不到。*/
for(int j=;j<=;j++)
for(int i=;i<=N;i++)
if(i+(<<j)-<=N)
f[i][j]=max(f[i][j-],f[i+(<<(j-))][j-]);
}
查询:若需要查询的区间为$[i,j]$,则需要找到两个覆盖这个闭区间的最小幂区间。
这两个区间可以重复,因为两个区间是否相交对区间最值没有影响。(如下图)
当然求区间和就肯定不行了。这也就是$RMQ$的限制性。
因为区间的长度为$j-i+1$,所以可以取$k=log_2(j-i+1)$。
则$RMQ(A,i,j)=max\{f(i,k),f(j-2^{k}+1,k)\}$。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int a[],f[][];
inline int read(){
int x=,f=;
char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-')
f=-;
for(;isdigit(c);c=getchar())
x=x*+c-'';
return x*f;
}
void RMQ(int N){
for(int j=;j<=;j++)
for(int i=;i<=N;i++)
if(i+(<<j)-<=N)
f[i][j]=max(f[i][j-],f[i+(<<(j-))][j-]);
}
int main(){
int N=read(),M=read();
for(int i=;i<=N;i++) a[i]=read();
for(int i=;i<=N;i++) f[i][]=a[i];
RMQ(N);
while(M--){
int i=read(),j=read();
int k=(int)(log((double)(j-i+))/log(2.0));
printf("%d\n",max(f[i][k],f[j-(<<k)+][k]));
}
return ;
}
【模板】RMQ问题的ST表实现的更多相关文章
- [poj3264]rmq算法学习(ST表)
解题关键:rmq模板题,可以用st表,亦可用线段树等数据结构 log10和log2都可,这里用到了对数的换底公式 类似于区间dp,用到了倍增的思想 $F[i][j] = \min (F[i][j - ...
- RMQ问题及ST表
RMQ(Range Minimum/Maximum Query)问题指的是一类对于给定序列,要求支持查询某区间内的最大.最小值的问题.很显然,如果暴力预处理的话复杂度为 \(O(n^2)\),而此类问 ...
- 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)
题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...
- 【算法学习笔记】RMQ问题与ST表
\(0.\) RMQ问题 P1816 人话翻译 给定一个长度为\(n\)的数列\(a\),然后有\(m\)组询问,每次询问一个区间\([l,r]\)的最小值. 其中\(m,n\leq10^5\) \( ...
- RMQ算法使用ST表实现
RMQ RMQ (Range Minimum Query),指求区间最小值.普通的求区间最小值的方法是暴力. 对于一个数列: \[ A_1,~ A_2,~ A_3,~ \cdots,~ A_n \] ...
- 提高篇(1):RMQ问题与ST表
RMQ是英文Range Minimum/Maximum Query的缩写,是询问某个区间内的最值,这里讲一种解法:ST算法 ST算法通常用在要多次(10^6级别)询问区间最值的问题中,相比于线段树,它 ...
- rmq问题:ST表
存板子.O(nlogn)预处理,O(1)查询.空间O(nlogn). int d[1000006][25]; int mn[1000006]; void rmq_init() { for(int i= ...
- 洛谷 P2880 [USACO07JAN]Balanced Lineup G (ST表模板)
题意:给你一组数,询问\(q\)次,问所给区间内的最大值和最小值的差. 题解:经典RMQ问题,用st表维护两个数组分别记录最大值和最小值然后直接查询输出就好了 代码: int n,q; int a[N ...
- hdu6356 Glad You Came 杭电多校第五场 RMQ ST表(模板)
Glad You Came Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
随机推荐
- openwrt gstreamer实例学习笔记(七. gstreamer 缓冲区(Buffers)和事件(Events))
1)概述 管道的数据流由一组缓冲区和事件组成,缓冲区包括实际的管道数据,事件包括控制信息,如寻找信息和流的终止信号.所有这些数据流在运行的时候自动的流过管道. 2) 缓冲区(Buffers) 缓冲区包 ...
- 信雅达面试题atoi函数实现
atoi函数: 功 能: 把字符串转换成整型数. 名字来源:ASCII to integer 的缩写. 原型: int atoi(const char *nptr); 函数说明 参数nptr字符串,如 ...
- Mac中Maven的安装步骤
1.下载Maven,并解压到某个目录. 2.打开terminal,输入一下命令. open .bash_profile; 3.在bash_profile中,编辑文件 内容如下. 4.保存bash_p ...
- DT的jquery
IE8浏览器,打开页面提示脚本错误,query不识别,缺少")"等等, 各种删除,最后只保留引用jquery文件还是不行,最后更好jquery为jQuery v1.12.4 版本, ...
- var let Hositing const Temporal Dead Zone
var let Hositing const Temporal Dead Zone 临时死区
- How do I set the timeout for a JAX-WS webservice client?
How do I set the timeout for a JAX-WS webservice client? up vote58down votefavorite 27 I've used JAX ...
- MYSQL进阶学习笔记十二:MySQL 表分区!(视频序号:进阶_29,30)
知识点十三:MySQL 表的分区(29) 一.什么要采用分区: 分区的定义: 当数据量过大的时候(通常是指百万级或千万级数据的时候),这时候需要将一张表划分几张表存储.一些查询可以得到极大的优化,这主 ...
- MYSQL进阶学习笔记二:MySQL存储过程和局部变量!(视频序号:进阶_4-6)
知识点三:MySQL存储过程和局部变量(4,5,6) 存储过程的创建: 创建存储过程的步骤: 首先选中数据库 改变分隔符,不让分号作为执行结束的标记.(通常情况下,改变分隔符命令 DELIMI ...
- 创建Android本地repo
/**************************************************************************** * 创建Android本地repo * 说明 ...
- c++11实现DLL帮助类
用过DLL的人都会发现,在C++中调用dll中的函数有点繁琐,调用过程如下:在加载dll后还要定义一个对应的函数指针类型,接着调用GetProcAddress获取函数地址,再转成函数指针,最后调用函数 ...