$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表实现的更多相关文章

  1. [poj3264]rmq算法学习(ST表)

    解题关键:rmq模板题,可以用st表,亦可用线段树等数据结构 log10和log2都可,这里用到了对数的换底公式 类似于区间dp,用到了倍增的思想 $F[i][j] = \min (F[i][j - ...

  2. RMQ问题及ST表

    RMQ(Range Minimum/Maximum Query)问题指的是一类对于给定序列,要求支持查询某区间内的最大.最小值的问题.很显然,如果暴力预处理的话复杂度为 \(O(n^2)\),而此类问 ...

  3. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

  4. 【算法学习笔记】RMQ问题与ST表

    \(0.\) RMQ问题 P1816 人话翻译 给定一个长度为\(n\)的数列\(a\),然后有\(m\)组询问,每次询问一个区间\([l,r]\)的最小值. 其中\(m,n\leq10^5\) \( ...

  5. RMQ算法使用ST表实现

    RMQ RMQ (Range Minimum Query),指求区间最小值.普通的求区间最小值的方法是暴力. 对于一个数列: \[ A_1,~ A_2,~ A_3,~ \cdots,~ A_n \] ...

  6. 提高篇(1):RMQ问题与ST表

    RMQ是英文Range Minimum/Maximum Query的缩写,是询问某个区间内的最值,这里讲一种解法:ST算法 ST算法通常用在要多次(10^6级别)询问区间最值的问题中,相比于线段树,它 ...

  7. rmq问题:ST表

    存板子.O(nlogn)预处理,O(1)查询.空间O(nlogn). int d[1000006][25]; int mn[1000006]; void rmq_init() { for(int i= ...

  8. 洛谷 P2880 [USACO07JAN]Balanced Lineup G (ST表模板)

    题意:给你一组数,询问\(q\)次,问所给区间内的最大值和最小值的差. 题解:经典RMQ问题,用st表维护两个数组分别记录最大值和最小值然后直接查询输出就好了 代码: int n,q; int a[N ...

  9. hdu6356 Glad You Came 杭电多校第五场 RMQ ST表(模板)

    Glad You Came Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

随机推荐

  1. Python开发【2.3 模块】

    1.模块导入 import 模块名 from 模块名 import 函数/类/变量 2.模块路径 import sys sys.path 3.模块重新导入 Python3若想在同一次会话中再次运行文件 ...

  2. 基础才是重中之重~用好configSections让配置信息更规范

    对于小型项目来说,配置信息可以通过appSettings进行配置,而如果配置信息太多,appSettings显得有些乱,而且在开发人员调用时,也不够友好,节点名称很容易写错,这时,我们有几种解决方案 ...

  3. SSM整理笔记1——SSM网站初步功能设计

    前言 因为公司里一直用Hibernate,但是现在Mybatis是趋势,所以搭建一个Mybatis的网站框架,目的是:1摸清其功能特点,2为以后的项目增加框架选择(以前只用hibernate或者Spr ...

  4. kill 挂起 Apache Web Server

    [root@hadoop1 ~]# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8 ...

  5. oracle问题系列 : ORA-02290: 违反检查约束条件

    报错如下: ### Error updating database. Cause: java.sql.SQLIntegrityConstraintViolationException: ORA-022 ...

  6. atomic_cmpxchg()/Atomic_read()/Atomic_set()/Atomic_add()/Atomic_sub()/atomi

    [ 1.atomic_read与atomic_set函数是原子变量的操作,就是原子读和原子设置的作用.2.原子操作,就是执行操作的时候,其数值不会被其它线程或者中断所影响3.原子操作是linux内核中 ...

  7. spin_lock、spin_lock_irq、spin_lock_irqsave区别

    void spin_lock(spinlock_t *lock); void spin_lock_irq(spinlock_t *lock); void spin_lock_irqsave(spinl ...

  8. Web.xml配置----字符过滤器

    添加EncodingFilter类实现Filter接口 import javax.servlet.*;import javax.servlet.http.HttpServletRequest;impo ...

  9. 一步一步学Silverlight 2系列(13):数据与通信之WebRequest

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  10. C++数组作为函数参数的几个问题(转)

    本文需要解决C++中关于数组的2个问题:1. 数组作为函数参数,传值还是传址?2. 函数参数中的数组元素个数能否确定? 先看下面的代码. #include <iostream> using ...