RMQ算法分析

RMQ算法,是一个快速求区间最值的离线算法,预处理时间复杂度O(n*log(n)),查询O(1),所以是一个很快速的算法,当然这个问题用线段树同样能够解决。

问题:给出n个数ai,让你快速查询某个区间的的最值。

算法分类:DP+位运算

算法分析:这个算法就是基于DP和位运算符,我们用dp【i】【j】表示从第 i 位开始,到第 i + 2^j -1 位的最大值或者最小值。

那么我求dp【i】【j】的时候可以把它分成两部分,第一部分从 i 到 i + 2 ^( j-1 ) - 1 ,第二部分从 i + 2 ^( j-1 )  到 i + 2^j - 1 次方,其实我们知道二进制数后一个是前一个的二倍,那么可以把 i ---  i + 2^j  这个区间 通过2^(j-1) 分成相等的两部分, 那么转移方程很容易就写出来了。

转移方程: mm [ i ] [ j ] = max ( mm [ i ] [ j - 1 ] , mm [ i + ( 1 << ( j - 1 ) ) ] [ j - 1 ] );

代码:

void rmq_isit(bool ok)
{
    for(int i=1;i<=n;i++)
        mm[i][0]=mi[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=1;i+j-1<=n;i++)
        {
            if(ok)
                mm[i][j]=max(mm[i][j-1],mm[i+(1<<(j-1))][j-1]);
            else
                mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
        }

    }
}

那么查询的时候对于任意一个区间 l -- r ,我们同样可以得到区间差值 len = (r - l + 1)。

那么我们这一用小于2^k<=len,的 k 把区间分成可以交叉的两部分l 到 l+2^(k)- 1, 到 r -(1<<k)+1 到 r 的两部分,很easy的求解了。

查询代码:

int rmq(int l,int r)
{
    int k=0;
    while((1<<(k+1))<=r-l+1)
        k++;
    //printf("%d %d %d %d\n",l,l+(1<<k),r-(1<<k)+1,r-(1<<k)+1+(1<<k));
    int ans1=max(mm[l][k],mm[r-(1<<k)+1][k]);
    int ans2=min(mi[l][k],mi[r-(1<<k)+1][k]);
    return ans1-ans2;
}

顺便写一道练习题目:poj 3264 Balanced Lineup

求区间差值,那么很简单一个应用。

RMQ算法分析

时间: 2024-08-28 04:14:22

RMQ算法分析的相关文章

poj 3264 Balanced Lineup 区间极值RMQ

题目链接:http://poj.org/problem?id=3264 For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he wil

基于DP+位运算的RMQ算法

来源:http://blog.csdn.net/y990041769/article/details/38405063 RMQ算法,是一个快速求区间最值的离线算法,预处理时间复杂度O(n*log(n)),查询O(1),所以是一个很快速的算法,当然这个问题用线段树同样能够解决. 问题:给出n个数ai,让你快速查询某个区间的的最值. 算法分类:DP+位运算 算法分析:这个算法就是基于DP和位运算符,我们用dp[i ][j]表示从第 i 位开始,到第 i + 2^j -1 位的最大值或者最小值. 那么

dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:655   Accepted:54 [Submit][Status][Discuss] Description 已知一个长度为 n 的数组 a[1],a[2],-,a[n],我们进行 q 次询问,每次询问区间 a[l],a[l+1],-,a[r?1],a[r] ,数字从小到大

RMQ问题再临

RMQ问题再临 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 终于,小Hi和小Ho踏上了回国的旅程.在飞机上,望着采购来的特产——小Hi陷入了沉思:还记得在上上周他们去超市的时候,前前后后挑了那么多的东西,都幸运的没有任何其他人(售货员/其他顾客)来打搅他们的采购过程.但是如果发生了这样的事情,他们的采购又会变得如何呢? 于是小Hi便向小Ho提出了这个问题:假设整个货架上从左到右摆放了N种商品,并且依次标号为1到N,每次小Hi都给出一段区间[L, R],小Ho要做

算法分析的正确姿势

[本系列博文会对常见的数据结构及相应算法进行分析与总结,并会在每篇博文中提供几道相关的一线互联网企业面试/笔试题来巩固所学及帮助我们查漏补缺.项目地址:https://github.com/absfree/Algo.由于个人水平有限,叙述中难免存在不清晰准确的地方,希望大家可以指正,谢谢大家:)] 一.前言 在进一步学习数据结构与算法前,我们应该先掌握算法分析的一般方法.算法分析主要包括对算法的时空复杂度进行分析,但有些时候我们更关心算法的实际运行性能如何,此外,算法可视化是一项帮助我们理解算法

[bzoj3489]A simple rmq problem

本题既不是rmq也不会simple(对我这种蒟蒻而言) 一开始只能想到树套树套树TAT然后看了看数据范围果断滚去膜拜题解. 然后才知道预先排序一下可以弄掉一个log.不过得写可持久化线段树套可持久化线段树.. 然后愉悦的开码了...感人的是竟然不用调...更感人的是交上去直接tle了. 然后从网上找了别人的代码(方法一样)发现同样的数据我要跑6s+..标称只要2s+.. 之后各种卡常还是慢了一倍TAT...最后自己写个max函数就和标程一样快了TAT这几天怎么总是出些奇怪的状况QAQ. 本来故事

算法分析与设计复习

算法分析与设计复习 2016年初,研一上学期期末考试前,复习并总结算法分析与设计科目的内容.复习过程参照<算法导论>中文第2版,同时参照PPT,章节划分根据PPT内容 概要: 第一章 概述 第二章 插入排序&分治策略 第三章 复杂度分析 第四章 堆与堆排序 第五章 快速排序 第六章 线性时间排序 第一章 概述 算法的应用范围 算法在诸如生物等诸多领域有其应用 算法的意义 算法在很多情况下让不可能完成的事情变成了可能,让处理的很慢的过程变快. 一个铺垫 一串不全为0的数,怎么取能拿到一段

CodeForces 514D R2D2 and Droid Army RMQ+二分

题目链接:点击打开链接 题意:给定n m k 下面是n*m的矩阵 最多可以操作k次,每次操作可以使任意一列上所有的数 -= 1,( 0还是0) 要求得到连续最多的行数(每行里的整数都为0),输出任意一个方案(在每一列上操作的次数) 思路: 把每列单独考虑 枚举每行,二分找这行往下最多能清空的行数, RMQ维护一列的最大值. import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWr

poj 3264 Balanced Lineup RMQ线段树实现

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 36613   Accepted: 17141 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh