c++ RMQ

"本文介绍了RMQ(Range Max Number Query)算法,用于静态数据集的区间最大值查询。通过动态规划的方法,预先计算并存储每个子区间的最大值,查询时以 (O(1)) 的时间复杂度获取结果。预处理时间为 (O(n)),适用于大量查询场景。算法详细阐述了状态转移方程和查询过程,并提供了C++实现代码。"
摘要由CSDN通过智能技术生成

关于

RMQ ,即 Range Maxnum (Minnum) Query 。用于查询静态区间最大(最小)值,
思路基于动态规划 (DP)

思路

设 F[i][j] 为 [i,i+2j] 区间内的的最大值,那么 F[i][0] 就是我们输入的数。
不难想到一个区间可以被分成两边


当前区间的最大值就是左右两区间的最大值,即 \(F[i][j]=\max(F[i][j-1],F[i+2^{j-1}][j-1])\)

查询

对于区间 \([l,r]\) 先求 \(k=\lfloor \log^2_{r-l+1}\rfloor\)

答案即为 \(\max(F_{l,k},F_{r-2^k+1,k})\) 可以忽略中间重叠的部分,不影响结果

实现

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,T,l,r,k,f[100005][35],p[35]={1};
int main(){
	for(register int i=1;i<31;i++) p[i]=p[i-1]<<1;
	scanf("%d%d",&n,&T);
	for(register int i=1;i<=n;i++) scanf("%d",&f[i][0]);
	for(register int j=1;j<31;j++)
		for(register int i=1;i+p[j-1]-1<=n;i++)
			f[i][j]=max(f[i][j-1],f[i+p[j-1]][j-1]);
	while(T--){
		scanf("%d%d",&l,&r);
		k=log2(r-l+1);
		printf("%d\n",max(f[l][k],f[r-p[k]+1][k]));
	}
}

时间复杂度:\(O(n)\)预处理,\(O(1)\)查询,可用于大量查询的静态区间
动态的话还是要考虑线段树等数据结构

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值