初识RMQ算法

这个RMQ算法是专门针对于求最值的高效算法。其思路比较简单,先是利用DP预处理,之后便是查询,方法如下:

假如我们需要查询的区间为(i,j),那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可以重复,比如查询5,6,7,8,9,我们可以查询5678和6789)。

因为这个区间的长度为j - i + 1,所以我们可以取k=log2( j - i + 1),则有:RMQ(A, i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}。

举例说明,要求区间[2,8]的最大值,k = log2(8 - 2 + 1)= 2,即求max(F[2, 2],F[8 - 2 ^ 2 + 1, 2]) = max(F[2, 2],F[5, 2])。

具体应用:poj3264

下面给出代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,h[50005][25],f[50005][25];
void rmq(int x)
{
    for (int j=1;j<20;j++)
     for (int i=1;i<=x;i++)
     {
         if(i+(1<<j)-1<=x)
         {
              h[i][j]=max(h[i][j-1],h[i+(1<<(j-1))][j-1]);
              f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
         }
     }
}
int main()
{
    int t;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&h[i][0]);
            f[i][0]=h[i][0];
        }
        rmq(n);
        int a,b,maxl,minl;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            int k=(int)(log(b-a+1)/log(2.0));
            maxl=max(h[a][k],h[b-(1<<k)+1][k]);
            minl=min(f[a][k],f[b-(1<<k)+1][k]);
            printf("%d\n",maxl-minl);
        }
    }
    return 0;
}

清清正正射命丸文是也~

时间: 2024-10-20 09:24:29

初识RMQ算法的相关文章

谈谈RMQ算法

没用的话:好像好久没更博了,无聊就讲讲算法吧(主要找不到水题). 感觉针对初学者,老师教这个算法时没怎么懂,最近(大概1.2个月前吧)老师又教了lca(最近公共祖先,额,可以百度,我就不讲了,可能以后会再写一篇博客关于这个)讲到lca转RMQ才又回来认真复(xue)习(xi).大概搞懂了,本质是dp. 认识RMQ: 要学习RMQ,首先要知道RMQ求什么吧? RMQ简单来说就是求区间的最大值(最小值). 什么?没懂! 举个栗子: 1  -2  9  10  15  38  -9 这里有 7 个数(

RMQ算法

上午在做一个题,结果怎么也做不出来,然后看了篇博客,发现其在求最小的字典序的时候用到了RMQ算法. 问徐大佬这是个什么东西,大佬说:你们肯定学过,这个东西1个月以前60级的就问过我了. 为了不让学弟学妹落下,我决定还是学学RMQ算法吧.. one  前言 RMQ(Range Minimum/Maximum Query),是指区间查询最值的算法,我们对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n)是求在序列A中,在区间i,j中出现的最小/最大值. two  RMQ算法 对于该

【足迹C++primer】31、初识泛型算法

初识泛型算法 理解算法的最基本方法是了解他们是否读取元素.改变元素或是重排元素顺序! 只读算法 #include<iostream> #include<numeric> using namespace std; //对vec中的元素求和,初值是0 int sum=accumulate(vec.cbegin(), vec.cend(), 0); 这里面第三个参数决定了函数使用哪个加法运算符以及返回值类型. 算法和元素类型 string sum=accumulate(v.cbegin(

RMQ 算法入门

1. 概述 RMQ(Range Minimum/Maximum Query).即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值. 这两个问题是在实际应用中常常遇到的问题.以下介绍一下解决这两种问题的比較高效的算法.当然,该问题也能够用线段树(也叫区间树)解决,算法复杂度为:O(N)~O(logN),这里我们暂不介绍. 2.RMQ算法 对于该问题,最easy想到的解决方式是遍历,复杂度是O(n).但当

nyoj 119士兵杀敌(三)(线段树区间最值查询,RMQ算法)

题目119 题目信息 执行结果 本题排行 讨论区 士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描写叙述 南将军统率着N个士兵,士兵分别编号为1~N,南将军常常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比較,计算出两个人的杀敌数差值.用这样的方法一方面能鼓励杀敌数高的人,还有一方面也算是批评杀敌数低的人,起到了非常好的效果. 所以,南将军常常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少. 如今,请你写一个程

RMQ算法讲解

RMQ算法 引入: 例1.题目描述 输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数之间的最大值. 第一种方法:大暴力之术. 但是……时间复杂度最坏会达到 $O(NM)$,一半左右的点绝对爆T. 所以,引入了————RMQ! RMQ:Range Maximum(Minimum) Query的缩写,顾名思义是用来求某个区间内的最大值或最小值,通常用在需要多次询问一些区间的最值的问题中. RMQ的原理是 动态规划 用A[1..N]表示一组数,F[I,J]表示从A[I]到A[I+2

初识聚类算法:K均值、凝聚层次聚类和DBSCAN

原文地址http://blog.sina.com.cn/s/blog_62186b460101ard2.html 这里只是将比较重要的部分转一下 另外还有一篇关于层次聚类的 http://blog.csdn.net/jwh_bupt/article/details/7685809 聚类分析就仅根据在数据中发现的描述对象及其关系的信息,将数据对象分组(簇).其目标是,组内的对象相互之间是相似的,而不同组中的对象是不同的.组内相似性越大,组间差别越大,聚类就越好. 先介绍下聚类的不同类型,通常有以下

RMQ 算法

1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值.这两个问题是在实际应用中经常遇到的问题,下面介绍一下解决这两种问题的比较高效的算法.当然,该问题也可以用线段树(也叫区间树)解决,算法复杂度为:O(N)~O(logN),这里我们暂不介绍. 2.RMQ算法 对于该问题,最容易想到的解决方案是遍历,复杂度是O(n).但当数据量

hdu 2586 + hdu 4123(RMQ算法与LCA)

转自:http://blog.csdn.net/liang5630/article/details/7917702 rmq算法可用来求区间最值,区间最值差,树上最近公共祖先,时间复杂度O(nlogn) 1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值.这两个问题是在实际应用中经常遇到的问题,下面介绍一下解决这两种问题的比较