title: RMQ_第一弹_Sparse Table
date: 2018-09-21 21:33:45
tags:

  • acm
  • RMQ
  • ST
  • dp
  • 数据结构
  • 算法
    categories:
  • ACM

概述

RMQ (Range Minimum/Maximum Query)

从英文便可以看出这个算法的主要是询问一个区间内的最值问题,,,

暑假集训的时候学习了 线段树 ,,,

也可以对给定数组查询任意区间的最值问题,,,,

这两个主要的区别就是 线段树 可以进行单点的修改操作,,,而 Sparse Table 算法不能进行点修改,,

或者说这样修改一次重预处理一次不划算,,,

所以说,,要是题目只是单纯的多次查询任意区间的最值,,,Sparse Table 首选,,毕竟,,毕竟写起来比线段树简单得多了,,,

预处理

算法原理

基本思想是dp,,,,

dp的状态 : 对于数组 \(a[1-n]\) , \(F[i , j]\)表示从第 \(i\) 个位置开始 , 长度 为\(2^j\) 个数这个区间中的最值,,,;

dp的初始值 : \(F[i , 0] = a[i]\);

状态转移方程 : \(F[i , j] = max (F[i , j - 1] , F[i + 2^{j - 1} , j - 1])\);

思想 : \(F[i , j]\) 就是不断取他的左右这两段的最值,,这两段的长度相等,都为 \(2^{j - 1}\) 个元素,,

实现

const int maxn = 5e4 + 10;
int n , q;
int a[maxn];
int mx[maxn][20];
int mi[maxn][20];
void rmq()
{for (int i = 1; i <= n; ++i)mx[i][0] = mi[i][0] = a[i];for (int j = 1; (1 << j) <= n; ++j){for (int i = 1; i + (1 << j) - 1 <= n; ++i){mx[i][j] = max(mx[i][j - 1] , mx[i + (1 << (j - 1))][j - 1]);mi[i][j] = min(mi[i][j - 1] , mi[i + (1 << (j - 1))][j - 1]);}}
}

这里我们需要注意的是循环的顺序,我们发现外层是j,内层所i,这是为什么呢?可以是i在外,j在内吗?
答案是不可以。因为我们需要理解这个状态转移方程的意义。

状态转移方程的含义是:先更新所有长度为F[i,0]即1个元素,然后通过2个1个元素的最值,获得所有长度为F[i,1]即2个元素的最值,然后再通过2个2个元素的最值,获得所有长度为F[i,2]即4个元素的最值,以此类推更新所有长度的最值。

而如果是i在外,j在内的话,我们更新的顺序就是F[1,0],F[1,1],F[1,2],F[1,3],表示更新从1开始1个元素,2个元素,4个元素,8个元素(A[0],A[1],....A[7])的最值,这里F[1,3] = max(max(A[0],A[1],A[2],A[3]),max(A[4],A[5],A[6],A[7]))的值,但是我们根本没有计算max(A[0],A[1],A[2],A[3])和max(A[4],A[5],A[6],A[7]),所以这样的方法肯定是错误的。

本段来自某大佬博客


查询

思想

假如我们需要查询的区间为(i,j),那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可以重复,比如查询5,6,7,8,9,我们可以查询5678和6789)。

因为这个区间的长度为 \(j - i + 1\) ,所以我们可以取 \(k=log2( j - i + 1)\) ,则有:\(RMQ(A, i, j)=max(F[i , k], F[ j - 2 ^ k + 1, k])\)。

举例说明,要求区间[2,8]的最大值,\(k = log_2(8 - 2 + 1)= 2\),即求 \(max(F[2, 2],F[8 - 2 ^ 2 + 1, 2]) = max(F[2, 2],F[5, 2])\);

实现

int ans(int l , int r)
{int k = 0;int len = r - l + 1;while ((1 << (k + 1)) <= len)++k;return max (mx[l][k] , mx[r - (1 << k) + 1][k]) - min (mi[l][k] , mi[r - (1 << k) + 1][k]);
}

实战

题目链接

题目大意: 给定的数列a[1 - n] , 求出[l , r]这个区间内的极差 , 即最大值与最小值的差

直接套板子,,,,

ac代码:

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 5e4 + 10;
int n , q;
int a[maxn];
int mx[maxn][20];
int mi[maxn][20];
void rmq()
{for (int i = 1; i <= n; ++i)mx[i][0] = mi[i][0] = a[i];for (int j = 1; (1 << j) <= n; ++j){for (int i = 1; i + (1 << j) - 1 <= n; ++i){mx[i][j] = max(mx[i][j - 1] , mx[i + (1 << (j - 1))][j - 1]);mi[i][j] = min(mi[i][j - 1] , mi[i + (1 << (j - 1))][j - 1]);}}
}
int ans(int l , int r)
{int k = 0;int len = r - l + 1;while ((1 << (k + 1)) <= len)++k;return max (mx[l][k] , mx[r - (1 << k) + 1][k]) - min (mi[l][k] , mi[r - (1 << k) + 1][k]);
}
using namespace std;
int main(){ while (scanf("%d%d" , &n , &q) != EOF){for (int i = 1; i <= n; ++i)scanf("%d" , &a[i]);rmq();while (q--){int l , r;scanf("%d%d" , &l , &r);printf("%d\n" , ans(l , r));}}return 0;
}

kuangbin的板子:

一维:

const int MAXN = 50010;
int dp[MAXN][20];
int mm[MAXN];
//初始化 RMQ, b 数组下标从 1 开始,从 0 开始简单修改
void initRMQ(int n,int b[])
{mm[0] = −1;for(int i = 1; i <= n; i++){mm[i] = ((i&(i−1)) == 0)?mm[i−1]+1:mm[i−1];dp[i][0] = b[i];}for(int j = 1; j <= mm[n]; j++)for(int i = 1; i + (1<<j) −1 <= n; i++)dp[i][j] = max(dp[i][j−1],dp[i+(1<<(j−1))][j−1]);
}//查询最大值
int rmq(int x,int y)
{int k = mm[y−x+1];return max(dp[x][k],dp[y−(1<<k)+1][k]);
}

转载于:https://www.cnblogs.com/31415926535x/p/9688994.html

RMQ_第一弹_Sparse Table相关推荐

  1. MaxCompute - ODPS重装上阵 第一弹 - 善用MaxCompute编译器的错误和警告

    摘要: MaxCompute (ODPS) ( 注1 )是阿里云自主研发的具有业界领先水平的分布式大数据处理平台, 尤其在集团内部得到广泛应用,支撑了多个BU的核心业务. ODPS2.0除了持续优化性 ...

  2. Selenium 抓取玩加赛事数据第一弹

    抓取玩加赛事的王者荣耀的相关数据第一弹--->战队基本信息 一.页面分析 1.战区分析 目前的玩加赛事王者荣耀页面,全球 和中国 的数据是完全一样的.所以抓取任务只涉及全球.后期更新任务应该考虑 ...

  3. 前端面试题整理——(第一弹 HTML和CSS)

    文章目录 前端面试题整理--(第一弹 HTML和CSS) 1. 你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? 2. 每个HTML文件里开头都有个很重要的东西,Doctype,知道这是干什 ...

  4. 阿里达摩院2020趋势第一弹:感知智能的“天花板”和认知智能的“野望”

    作者 | Just 出品 | AI科技大本营(ID:rgznai100) "感知智能与认知智能是相辅相成的关系.认知智能需要感知系统来进行信号处理和概念识别,而感知系统也需要认知系统的反馈来 ...

  5. 阿里达摩院2020趋势第一弹:感知智能的“天花板”和认知智能的“野望”(附链接)...

    授权自AI科技大本营(ID:rgznai100) 本文约2900字,建议阅读8分钟 本文是采访了达摩院资深算法专家杨红霞,就感知智能向认知智能的演进和变革进行更深入解读. "感知智能与认知智 ...

  6. 智能车百度赛道培训第一弹-基础篇

    智能车百度赛道培训第一弹--基础篇来啦!请查收! ▌基础篇 01.培训安排 时间安排: 2021年3月19日(周五) 晚8:30 内容简介: 由百度赞助的人工智能创意组,今年竟然开始要求学生做车了?这 ...

  7. 智能车大赛AI视觉组培训第一弹——基础篇

    智能车大赛AI视觉组培训第一弹: ▌基础篇 1.培训简介 ■时间安排: 2021年03月18日 14:00 ■内容简介: 由恩智浦赞助的AI视觉组,今年由于把人工智能应用在智能车竞赛中,使得难度提升了 ...

  8. 获取frame_用Python获取可能是全网最全的杰尼龟表情包(第一弹)

    杰尼龟系列表情包在广大网友之间传递快乐,红极一时.我想是杰尼龟可爱的外表以及憨憨的形态,圆圆的脸蛋大大的眼睛,且其经常在剧中摆出各式夸张表情,因而被广大网友制成各式各样的表情包,并且深受沙雕网友的喜爱 ...

  9. ubuntu服务器mysql管理 第一弹

    2019独角兽企业重金招聘Python工程师标准>>> 第一弹.在Ubuntu服务器上安装MySQL 注:服务器管理通过SecureCRT来管理操作. 由于Linux的强大,对于大多 ...

  10. 与阿里云容器服务 ACK 发行版的深度对话第一弹:如何借助 sealer 实现快速构建 部署

    作者:淮右.王飞.瑜佳 记者: 阿里云原生的读者朋友们大家好,今天应广大感兴趣朋友们的强烈要求,我们邀请来了「阿里云容器服务 ACK 发行版」做客我们的栏目,为大家讲述它的身世之谜,以及它是如何和伙伴 ...

最新文章

  1. FreeSWITCH配置文件详解
  2. 北京python培训班价格-北京Python编程培训多少钱
  3. selenium自动化之鼠标操作
  4. c#中datareader中HasRows属性和Read方法的区别
  5. 谈谈redis,memcache的区别和具体应用场景
  6. 从零开发一个命令行脚手架工具 等
  7. golang xorm框架对应pg数据库字段类型参照表
  8. Xcode升级后插件失效
  9. 我为什么要用 Javascript 编写 CSS?
  10. 已收藏!java自学网址
  11. 用 C# 实现带键值的优先队列
  12. 推荐系统之隐语义模型(LFM)及Python实现
  13. 打怪小游戏(快做完了)
  14. Mobicomm 2019
  15. 源自神话的写作要义之英雄
  16. 数据同步工具—SeaTunnel简介
  17. 上海交通大学python期末考试样题加解析_上海交通大学python期末考试样题加解析...
  18. 基于arduino和openmv的智能小车设计制作流程
  19. PMOS管经典开关电路-PMOS开关典型电路工作原理及分析-KIA MOS管
  20. windows_server2008操作系统切换语言

热门文章

  1. IdleHandler,页面启动优化神器
  2. 一些有价值的工作建议
  3. [清华集训2016]温暖会指引我们前行——LCT+最大生成树
  4. SpringCloud之 Feign的简单使用
  5. wdcp 开启某个Mysql数据库远程访问
  6. 网络互撕是群体极化的典型症状
  7. CentOS 7部署Kafka和Kafka集群
  8. SurfaceView的绘图机制
  9. Hadoop大数据之Debug
  10. 今晚去参加了ZTE IP产品线的活动