RMQ(区间最值查询 模板)
发布日期:2021-11-02 09:48:42 浏览次数:2 分类:技术文章

本文共 1053 字,大约阅读时间需要 3 分钟。

RMQ(Range Minimum/Maximum Query)

目的:针对多次询问区间的最值问题。

RMQ算法一般用较长时间做预处理。
时间复杂度:为O(nlogn),可以在O(1)的时间内处理每次查询。

解释

二维数组 dp[i][j] 表示从第 i 位开始连续 2j 个数中的最小值。

d p [ i ] [ j ] dp[i][j] dp[i][j] 的时候可以把它分成两部分:
第一部分是从 i i i i + 2 j − 1 − 1 i+2^{j-1}-1 i+2j11
第二部分从 i + 2 j − 1 i+2^{j-1} i+2j1 i + 2 j − 1 i+2^j-1 i+2j1
因为二进制数前一个数是后一个的两倍,那么可以把 i i i i + 2 j − 1 i+2^{j-1} i+2j1 这个区间通过 2 j − 1 2^{j-1} 2j1 分成相等的两部分, 那么转移方程很容易就写出来了。
d p [ i ] [ 0 ] dp[i][0] dp[i][0] 就表示第 i 个数字本身)
d p [ i ] [ j ] = m i n ( d p [ i ] [ j − 1 ] , d p [ i + ( 1 < < j − 1 ) ] [ j − 1 ] ) dp[i][j] = min(dp [i][j - 1], dp [i + (1 << j - 1)][j - 1]) dp[i][j]=min(dp[i][j1],dp[i+(1<<j1)][j1])

模板代码
void rmq_init() {
for (int i = 1; i <= N; i++) //初始化,arr为初始输入数组 dp[i][0] = arr[i]; for (int j = 1; (1 << j) <= N; j++) for (int i = 1; i + (1 << j) - 1 <= N; i++) dp[i][j] = min(dp[i][j - 1], dp[i + (1 << j - 1)][j - 1]);}int rmq_query(int l, int r) {
int k = log2(r - l + 1); return min(dp[l][k], dp[r - (1 << k) + 1][k]);}

转载地址:https://blog.csdn.net/weixin_43820352/article/details/108564042 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:51nod 1487 占领资源(RMQ,暴力,离散化)
下一篇:排列问题(全排列,next_permutation)

发表评论

最新留言

不错!
[***.144.177.141]2024年03月25日 02时03分36秒