C++ 实现区间最大值 RMQ 查询的高效分块算法复杂度优化【实战】

风枫吖_2125

风枫吖_2125

2026-05-11

738人浏览

原创

分块算法是兼顾时间与空间的RMQ实用方案:预处理将数组分为⌊√n⌋大小的块并计算每块最大值;查询时分类处理同块、残段和完整块,复杂度O(√n);通过2的幂次块大小和向量化优化缓存与性能。

c++ 实现区间最大值 rmq 查询的高效分块算法复杂度优化【实战】

如果您需要在C++中实现区间最大值查询(RMQ),且对查询效率有较高要求,但又不希望使用空间开销较大的稀疏表(ST表)或构建复杂度较高的线段树,则分块算法是一种兼顾时间与空间的实用选择。以下是针对该问题的高效分块实现步骤:

一、分块预处理:对每块内元素计算块内最大值

将原数组划分为若干大小为 ⌊√n⌋ 的连续块,对每个块单独遍历一次,记录该块内部的最大值并存入块最大值数组 block_max[]。此步骤确保后续跨块查询时可直接使用块级极值信息,避免逐个比较。

1、计算块大小 block_size = static_cast(std::sqrt(n));

2、确定总块数 num_blocks = (n + block_size - 1) / block_size;

3、对每个块索引 i(从 0 到 num_blocks - 1),遍历其覆盖范围 [i * block_size, min((i + 1) * block_size - 1, n - 1)],更新 block_max[i] = max(arr[j]);

二、查询优化:分类处理完全覆盖块与边界残段

对于任意查询区间 [L, R],将其拆解为左残段、中间完整块、右残段三部分。中间完整块的最大值可直接从 block_max[] 中 O(1) 获取;左右残段则需线性扫描,因长度均不超过块大小,故单次扫描代价为 O(√n)。

1、计算左端点所在块号 left_block = L / block_size,右端点所在块号 right_block = R / block_size;

2、若 left_block == right_block,则整个区间位于同一块内,直接遍历 arr[L] 至 arr[R] 求最大值;

3、否则,初始化答案为 max(left_segment_max, right_segment_max),其中左残段为 [L, (left_block + 1) * block_size - 1],右残段为 [right_block * block_size, R];

4、对中间块区间 [left_block + 1, right_block - 1],遍历对应 block_max[i] 并更新全局最大值;

三、空间压缩:复用块索引与动态块大小调整

为降低内存访问延迟并提升缓存命中率,采用紧凑的一维数组存储块最大值,并将块大小设为最接近 √n 的 2 的幂次(如 block_size = 1 (std::log2(std::sqrt(n)))),使块边界地址具备位运算对齐特性,加快索引计算速度。

1、计算近似块大小 block_size = 1;当 block_size * block_size 时,执行 block_size ;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

2、使用位移替代除法:块号计算改写为 block_id = index >> log2_block_size;

3、块最大值数组声明为 std::vector block_max(num_blocks),避免动态扩容带来的拷贝开销;

四、查询加速:预加载边界段起始地址与向量化比较

在查询前预先计算左右残段的起始指针与长度,利用现代CPU的SIMD指令集(如 SSE/AVX)对残段进行批量比较。由于残段长度上限为块大小(≤ √n),可安全启用 4/8 元素并行最大值计算,显著减少循环次数。

1、获取左残段首地址 auto left_ptr = &arr[L],长度 left_len = std::min(block_size - L % block_size, R - L + 1);

2、若 left_len >= 4,调用内联函数 _mm_max_epi32 对前 4 个元素做向量化求最大;

3、对剩余元素(

4、右残段同理处理,起始地址为 &arr[R - right_len + 1];

五、常数优化:避免分支预测失败与冗余取址

在查询主循环中消除条件跳转,将块内最大值查询逻辑展开为无分支代码路径。例如,通过位掩码与条件移动指令(cmov)替代 if-else,同时将数组访问模式改为单位步长连续读取,以匹配CPU预取器行为。

1、定义宏 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 并确保编译器内联;

2、对中间块循环,使用 for (int i = l_blk + 1; i ,禁止使用 i 等等价但触发额外比较的写法;

3、将 arr 和 block_max 声明为 const int* 类型,辅助编译器进行别名分析与寄存器分配;

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2288

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

347

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1345

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习