【模板】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 inittab
OpenWrt 启动时会执行 rc.d/ 下的脚本. 这篇文章 介绍了启动脚本里的规则. K50dropbear -> ../init.d/dropbear K85odhcpd -> .. ...
- LeetCode(67)题解: Add Binary
https://leetcode.com/problems/add-binary/ 题目: Given two binary strings, return their sum (also a bin ...
- java序员必备的十大技能
想成为一名出色的Java程序员么?本文将为大家重点介绍程序员必备的十大技能,成就您的梦想. 1.语法:必须比较熟悉,在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息知道是什么样 ...
- (最新)各大公司Java后端开发面试题总结
ThreadLocal(线程变量副本) Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量. 采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一 ...
- Spring Boot 整合Filter
两种方法 方法一: 正常创建好Filter类,配置完成 package clc.user.filter; import javax.servlet.Filter; import javax.servl ...
- 树状数组(二叉索引树 BIT Fenwick树) *【一维基础模板】(查询区间和+修改更新)
刘汝佳:<训练指南>Page(194) #include <stdio.h> #include <string.h> #include <stdlib.h&g ...
- 一步一步学Silverlight 2系列(12):数据与通信之WebClient
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- 识别String类型变量的问题
碰到了android无法识别string的问题 Cursor cursor = db.query(true, "user", new String[]{"id" ...
- iOS NSInteger/NSUInteger与int/unsigned int、long/unsigned long之间的区别!
在iOS开发中经常使用NSInteger和NSUInteger,而在其他的类似于C++的语言中,我们经常使用的是int.unsigned int.我们知道iOS也可以使用g++编译器,那么它们之间是否 ...
- iOS成员变量、实例变量、属性变量三者的联系与区别
一.类Class中的属性property 在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是 ...