高级搜索——ST表,离线RMQ问题

文章目录

    • 前言
    • 可重复贡献问题
    • ST表的定义
    • ST表的存储结构
    • ST表的预处理
      • 预处理的实现
    • ST表的区间查询
      • 对于k的获取
      • 区间查询的实现
    • OJ链接

前言

对于查询区间最值的方法,我们常用的就是线段树,树状数组,单调队列,而树状数组更适合用于快速求区间和,而单调队列维护区间最值只在特殊情况下适用,最无解的线段树空间开销大,而且有一定的代码量,它在动态维护区间最值上基本上可以说是最优解,但是如果是离线询问的话,本文将介绍的ST表,代码量远小于线段树,而且还能达到不错的时间复杂度。

可重复贡献问题

可重复贡献问题是指,对于运算opt ,任意操作数x,都满足x opt x = x。例如,max(x , x) = x , gcd(x , x) = x,因此,RMQ(区间最值查询)和区间gcd问题也是可重复贡献问题。

ST表的定义

ST表(Sparse Table)稀疏表,是一种适用于符合结合律且可重复贡献的信息查询的数据结构,如区间最大值、最小值、最大公因数,最小公倍数,按位或,按位与等。在处理RMQ(查询区间最值)问题时,通过倍增思想,我们可以以O(nlogn)预处理,从而实现O(1)查询。

ST表的存储结构

ST表的存储结构非常简单,就是一个二维数组f , 其中,f[i][j]代表以第i个数为起点,长度为2^j次方的区间内的最值

我们接下来均以最大值做讨论。

#define N 100010
int f[N][20];

ST表的预处理

我们如何去获取这样一个ST表呢?

对于一个大问题我们可以将其拆解为若干个小问题,利用其可重复贡献性来逐步得到我们问题的答案。

ST表以倍增法递推来预处理ST表,其实是一种自下而上的动态规划。

对于一个区间最大值而言,显然等于两个等长子区间最大值的最大值。那么根据我们f[i][j]的定义,可有如下递推公式:
f [ i ] [ j ] = m a x ( f [ i ] [ j − 1 ] , f [ 1 + ( i + 2 j − 1 ] [ j − 1 ] ) f[i][j] = max(f[i][j-1] , f[1+(i+2^{j-1}][j-1]) f[i][j]=max(f[i][j1],f[1+(i+2j1][j1])
那么我们只需要固定区间长度然后枚举起点,自下而上进行动态规划即可,由于区间长度每次倍增,所以不难得出我们的时间复杂度为O(nlogn)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预处理的实现

实现流程:

  • 目标序列arr,长度为n,下标从1开始
  • 初始化f[i][0]为arr[i]
  • 枚举长度j,然后枚举起点i进行状态转移
  • 注意区间边界和位运算优先级
    for (int i = 1; i <= n; i++)
        f[i][0] = arr[i];
    for (int j = 1; j <= 20; j++)
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
            f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);

ST表的区间查询

我们ST表能够实现对于任意区间[l , r](1<= l,r <=n)内的最值查询,那么是如何实现的呢?

我们已经知道了区间最值可以有子区间最值转移而来,那么对于区间[l , r]我们一定可以找到k,使得
2 k ≤ log ⁡ 2 ( r − l + 1 ) < 2 k + 1 2^{k}\le\log_{2}{(r - l + 1)}<2^{k+1} 2klog2(rl+1)<2k+1
那么我们可以得到分别以l为左端点和以r为右端点的两个长度为2^k的区间,这两个区间的最值的最值就是我们[l , r]区间内的最值。
q u e r y ( l , r ) = m a x ( f [ l ] [ k ] , f [ r − 2 k + 1 ] [ k ] ) query(l , r) = max(f[l][k],f[r-2^{k}+1][k]) query(l,r)=max(f[l][k],f[r2k+1][k])
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于k的获取

k显然就是log2 (r - l + 1)向下取整,这里我们有两种方案获取log2值

F1 递推预处理

观察下2^n求和公式很容易想明白这个递推,我们O(n)预处理,分摊每次取log2为O(1)

//int Log2[N]{0};
for (int i = 2; i <= n; ++i)
    Log2[i] = Log2[i / 2] + 1;

F2 直接用cmath里的log2

区间查询的实现

    for (int i = 0; i < n; i++)
    {
        //l = read(), r = read();
        cin >> l >> r;
        int k = log2(r - l + 1);
        cout << max(f[l][k], f[r - (1 << k) + 1][k]) << " ";
        //write(max(f[l][k], f[r - (1 << k) + 1][k])), putchar(' ');
    }

到此ST表的原理及实现就结束了,代码量非常少,在处理离线查询跟线段树的代码量比起来,显然这个出错率更低。

我们上面都是以最大值为例进行实现的,在实际应用中只要是满足结合律且可重复贡献的信息查询都在ST表的解决范围内,因为ST表能够对两个交集非空的子区间进行信息合并,这也就是重复贡献的精妙之处。

OJ链接

A几个水题爽一下

找几个板子题练练手

P3865 【模板】ST 表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P1816 忠诚 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

[P2880 USACO07JAN] Balanced Lineup G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/227416.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI报告专题:创造性和生成式人工智能

今天分享的AI系列深度研究报告&#xff1a;《AI报告专题&#xff1a;创造性和生成式人工智能》。 &#xff08;报告出品方&#xff1a;Capgemini&#xff09; 报告共计&#xff1a;64页 AI一代 生成式人工智能 (AI)正在迅速改变我们与技术的交互方式&#xff0c;使机器能够创…

Java实现屏幕截图程序(一)

在Java中&#xff0c;可以使用Robot类来实现屏幕截图程序。Robot类提供了一组用于生成输入事件和控制鼠标和键盘的方法。 Java实现屏幕截图的步骤如下&#xff1a; 导入Robot类 import java.awt.Robot;创建Robot对象 Robot robot new Robot();获取屏幕分辨率信息 Dimensi…

redis-学习笔记(hash)

Redis 自身已经是 键值对 结构了 Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成后, 到了 value 这一层, 还可以用 哈希类型 来组织 (简单的说就是哈希里面套哈希 [数组里面套数组 -> 二维数组] ) [ field value ] hset key field value [ field va…

urllib 异常、cookie、handler及代理(四)

目录 一、urllib异常 二、urllib cookie登录 三、urllib handler 处理器的基本使用 四、urllib 代理和代理池 参考 一、urllib异常 URLError/HTTPError 简介&#xff1a; 1.HTTPError类是URLError类的子类 2.导入的包urllib.error.HTTPError urllib.error.URLError 3.h…

如何将idea中导入的文件夹中的项目识别为maven项目

问题描述 大家经常遇到导入某个文件夹的时候&#xff0c;需要将某个子文件夹识别为maven项目 解决方案

XUbuntu22.04之8款免费UML工具(一百九十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【计算机组成体系结构】SRAM和DRAM

RAM — Random Access Memory 随机访问存储器 —指定某一存储单元地址的时候&#xff0c;存储单元的读取速度并不会因为存储单元的物理位置改变 SRAM即为 Static RAM 静态随机访问存储器 — 用于主存DRAM即为 Dynamic RAM 动态随机访问存储器 — 用于Cache 一、SRAM和DRAM的特…

oomall课堂笔记

一、项目分层结构介绍 controller层&#xff08;控制器层&#xff09;&#xff1a; 作用&#xff1a;负责输出和输入&#xff0c;接收前端数据&#xff0c;把结果返回给前端。 1.处理用户请求&#xff0c;接收用户参数 2.调用service层处理业务&#xff0c;返回响应 servi…

Javaweb之Maven仓库的详细解析

2.3 Maven仓库 仓库&#xff1a;用于存储资源&#xff0c;管理各种jar包 仓库的本质就是一个目录(文件夹)&#xff0c;这个目录被用来存储开发中所有依赖(就是jar包)和插件 Maven仓库分为&#xff1a; 本地仓库&#xff1a;自己计算机上的一个目录(用来存储jar包) 中央仓库&a…

利用R语言heatmap.2函数进行聚类并画热图

数据聚类然后展示聚类热图是生物信息中组学数据分析的常用方法&#xff0c;在R语言中有很多函数可以实现&#xff0c;譬如heatmap,kmeans等&#xff0c;除此外还有一个用得比较多的就是heatmap.2。最近在网上看到一个笔记文章关于《一步一步学heatmap.2函数》&#xff0c;在此与…

python 涉及opencv mediapipe知识,眨眼计数 供初学者参考

基本思路 我们知道正面侦测到人脸时&#xff0c;任意一只眼睛水平方向上的两个特征点构成水平距离&#xff0c;上下两个特征点构成垂直距离 当头像靠近或者远离摄像头时&#xff0c;垂直距离与水平距离的比值基本恒定 根据这一思路 当闭眼时 垂直距离变小 比值固定小于某一个…

主动而非被动:确保网络安全运营弹性的途径

金融部门处理威胁的经验对网络安全领域的任何人都有启发——没有什么可以替代提前摆脱潜在的风险和问题。 从狂野西部的银行劫匪到勒索软件即服务 (RaaS)&#xff0c;全球金融生态系统面临的威胁多年来发生了巨大变化。技术进步带动了金融业的快速发展&#xff0c;从现金交易到…

【开放集检测OSR】open-set recognition(OSR)开集识别概念辨析

开放集学习 Openset Learning 主动学习 Active Learning 例外检测 Out-of-Distribution open-set recognition(OSR)开集识别 anomaly detection和outlier detection 文章目录 OOD检测OSR开放集识别OSR开放集识别在训练和测试阶段的数据集使用数据分布似然函数OSR开放集识别的特…

2023人工智能和市场营销的融合报告:创造性合作的新时代需要新的原则

今天分享的人工智能系列深度研究报告&#xff1a;《2023人工智能和市场营销的融合报告&#xff1a;创造性合作的新时代需要新的原则》。 &#xff08;报告出品方&#xff1a;M&CSAATCHITHINKS&#xff09; 报告共计&#xff1a;11页 生成型人工智能的兴起和重要性 生成式…

Dockerfile介绍

1. DockerFile介绍 dockerfile是用来构建docker镜像的文件&#xff01;命令参数脚本&#xff01; 构建步骤&#xff1a; 1、编写一个dockerfile文件 2、docker build 构建成为一个镜像 3、docker run运行镜像 4、docker push发布镜像&#xff08;DockerHub、阿里云镜像仓库…

开源MES/免费MES/开源MES生产流程管理

一、什么是MES生产管理流程 生产管理系统&#xff08;又称制造执行系统&#xff09;是一种集成了计划、生产、质量控制、库存管理和材料申请等生产流程的管理系统。工厂生产管理流程是企业中实现高效生产的重要一环。 二、工厂生产管理流程的步骤 步骤一&#xff1a;计划和排…

利用reddit的api进行爬虫

1 介绍 Reddit是一个社交新闻聚合网站&#xff0c;用户可以发布、评价和讨论各种话题。Reddit的内容涵盖了广泛的主题&#xff0c;可以从中获取大量的文本数据进行情绪分析。 2 注册 2.1 注册reddit 你需要先注册一个reddit的账号。 2.2 注册api https://www.reddit.com/…

[RK-Linux] 移植Linux-5.10到RK3399(四)| 检查HDMI配置与打开内核LOGO显示

文章目录 一、HDMI二、VOP三、显示内核LOGO一、HDMI RK3399 的 HDMI 接口如图: datasheet 介绍: HDMI 接口各个引脚的作用如下: 接口标签作用HDMI_TX0P HDMI_TX0PA差分信号线,用于传输 HDMI 通道 0 的正向数据HDMI_TX0N HDMI_TX0NA

ELK(三)—安装可视化工具

目录复制 目录 一、ElasticSearch-Head可视化工具介绍1.1特性&#xff1a;1.2用法&#xff1a; 二、安装2.1docker安装2.2Chrome插件安装 一、ElasticSearch-Head可视化工具介绍 ElasticSearch-Head 是一个基于浏览器的 Elasticsearch 可视化工具&#xff0c;它提供了一个直观…

C#大型LIS检验信息系统项目源码

LIS系统&#xff0c;一套医院检验科信息系统。它是以数据库为核心&#xff0c;将实验仪器与电脑连接成网&#xff0c;基础功能包括病人样本登录、实验数据存取、报告审核、打印分发等。除基础功能外&#xff0c;实验数据统计分析、质量控制管理、人员权限管理、试剂出入库等功能…