首页 > 其他分享 >ST表(RMQ问题)

ST表(RMQ问题)

时间:2024-11-07 09:57:24浏览次数:4  
标签:RMQ int 查询 问题 区间 ST 预处理 dp

算法理解

RMQ问题就是对与区间最值查询一类问题的总称

对于RMQ问题的求解主要有以下两种方式:

  • 线段树,建树O(n),查询O(logn),支持在线修改
  • ST表,预处理O(logn),查询O(1),不支持在线修改

这个单元主要讲解的是ST表

倍增思想

考虑一个数必然能被拆分成二进制,所以我们先预处理出 \(2^k\) 的答案,对于一次查询,我们直接将查询分为二进制各个位,按位依次求解即可,通常搭配预处理使用

ST表

本质上是对区间进行一个拆分,拆成一块一块,然后对块进行查询

正常的分块一个块长是 \(\sqrt n\),因为不需要进行修改操作(个人理解),所以我们可以将区间拆分的更细致一些,以至于块与块之间可以重叠

结合倍增思想,我们选择将块长定为 \(2^k\),对于每一个端点都求出从这个端点出发,覆盖 \(2^k\) 个点的区间的最值,具体拆分方式见下图

少一张图片

预处理

因为静态询问所以我们先预处理出这个倍增数组,因为 \(2^k=2^{k-1}+2^{k-1}\) 所以 \(2^k\) 的答案可以通过 \(2^{k-1}\) 递推得来,因为递推本质上是递推,所以我们将这个数组设为 \(dp[i][j]\) 表示从i开始经过 \(2^j\) 个点的区间的最大值

查询

我们想要查询 \((l,r)\) 的区间最值,可以将其拆分成两个可以重叠的区间,区间长度就是 \(log2(r-l+1)\) 就是最大的二进制位,第一个区间的左端点就是l,第二个区间的右端点就是r

\(ans=max(dp[l][k],dp[r-(1<<k)+1][k]))\)

代码

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int n,m,l,r;
int a[N],dp[N][40];
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		dp[i][0]=a[i];
	}
	for(int j=1;j<=32;j++){
		for(int i=1;i+(1ll<<j)-1<=n;i++){
			dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
		}
	}
	for(int i=1;i<=m;i++){
		scanf("%lld%lld",&l,&r);
		int k=log2(r-l+1);
		printf("%lld\n",max(dp[l][k],dp[r-(1<<k)+1][k]));
	}
}

T2:

直接把max改成gcd即可

考虑两个区间可以合并,当且仅当区间重复计算并不会对答案产生影响,因为查询时两个区间是重叠的

那我可不可以将ST表改成倍增我对区间(l,r),进行一个二进制拆分,然后使得区间查询时并不重复,就能实现O(logn)静态维护区间加区间乘呢?(问题暂且保留)

标签:RMQ,int,查询,问题,区间,ST,预处理,dp
From: https://www.cnblogs.com/zcxnb/p/18531599

相关文章

  • bp抓包与url栏所对应的文件问题处理
    如题:题目告诉我们是文件绕过问题打开web环境,题目是百度的界面,一开始我以为是我卡了。本题解题方法很多,只在这里展示一种看到url栏,发现直接就是一个子文件。但是删掉后缀发现网页打不开,选择用burpsuite进行抓包。打开内嵌浏览器,打开拦截,拦截后发送到repeater。在repeater中发......
  • 从 vue 源码看问题 — vue 中的 render helper 是什么?
    前言前面的文章中提到组件更新时,需要先执行编译器生成的渲染函数得到组件的vnode,而渲染函数生成vnode则是通过其中的_c、_l、、_v、_s等方法实现的.比如:普通节点被编译成了可执行_c函数v-for节点被编译成了可执行的_l函数…那么下面就一起来了解一下,什么......
  • 从 vue 源码看问题 — vue 编译器如何生成渲染函数?
    前言前两篇主要了解了vue编译器的解析和优化:将组件的html模版解析成AST对象基于AST语法树进行静态标记,首先标记每个节点是否为静态节点,然后进一步标记出静态根节点,便于在后续更新中跳过静态根节点的更新,从而提高性能下面就了解一下vue编译器是如何从AST......
  • HCL AppScan Standard 10.7.0 发布下载,新增功能介绍
    HCLAppScanStandard10.7.0(Windows)-Web应用程序安全测试HCLAppScanStandardv10forWindowsMultilingual请访问原文链接:https://sysin.org/blog/appscan-10/查看最新版。原创作品,转载请保留出处。作者主页:sysin.org市场领先的应用程序安全解决方案(SAST、DAST、I......
  • 如何编程求解俄罗斯方块游戏问题
    相关:对于特定的游戏问题使用启发式算法可以取得比AI算法更好的表现UsingA.I.toDOMINATENERDSinTETRISMachineLearning:AILearnsToPlayTetriswithConvolutionalNeuralNetworkAIlearnstoplayTetrisusingMachineLearningandConvolutionalNeuralNetwor......
  • Yesterday once more
    Yesterdayoncemore昨日重现 中英文歌词:WhenIwasyoungI'dlistentotheradio当我年少的时候,我总爱守在收音机旁Waitingformyfavoritesongs等待着我最心爱的歌曲从收音机里轻轻流淌。WhentheyplayedI'dsingalong,每当歌声响起,我都跟着哼唱,Itmakemesmile.这......
  • 超详细2024版Latex安装Texlive+Texstudio(含环境配置)
    一、软件介绍(一)Latex介绍LaTeX(LATEX,音译“拉泰赫”)是一种基于ΤΕΧ的排版系统,由美国计算机学家在20世纪80年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由ΤΕX所提供的强大功能,能在几天、甚至几小时内生成很多具有书籍质量的印刷品。对于生成......
  • test4
    如果你希望通过一个抽象类来处理不同类型的数据(例如数组和列表),而不想为每种类型创建具体的子类,可以在抽象类中直接实现对不同数据类型的处理逻辑。可以通过检查传入数据的类型来决定如何处理它们。以下是一个可能的设计:抽象类设计importjava.util.List;publicabstractclass......
  • test3
    为了创建一个能够处理不同数据类型(例如数组、列表等)的抽象类,我们需要做到以下几点:定义通用的抽象方法:这些方法用于处理数据的公共逻辑,例如生成列。采用泛型:利用Java的泛型来使抽象类更具灵活性,从而可以处理多种数据类型。提供默认实现或辅助方法:对于某些可以通用的逻辑,提供......
  • 【C++篇】在秩序与混沌的交响乐中: STL之map容器的哲学探寻
    文章目录C++`map`容器详解:高效存储与快速查找前言第一章:C++`map`的概念1.1`map`的定义1.2`map`的特点第二章:`map`的构造方法2.1常见构造函数2.1.1示例:不同构造方法2.2相关文档第三章:`map`的常用操作3.1插入操作详解3.1.1使用`insert()`插入元素3.1.2......