先写一道水题的博客,为后面要写的博客做一个铺垫。

ヾ(◍°∇°◍)ノ゙

RMQ(Range Minimum/Maximum Query),即区间最值查询,对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。

时间复杂度:

1、朴素(即搜索),O(n)-O(qn) online。
2、线段树,O(n)-O(qlogn) online。
3、ST(实质是动态规划),O(nlogn)-O(q) online。
ST算法(Sparse Table),以求最大值为例,设d[i,j]表示[i,i+2^j-1]这个区间内的最大值,那么在询问到[a,b]区间的最大值时答案就是max(d[a,k], d[b-2^k+1,k]),
其中k是满足2^k<=b-a+1(即长度)的最大的k,即k=[ln(b-a+1)/ln(2)]。d的求法可以用动态规划,d[i, j]=max(d[i, j-1],d[i+2^(j-1), j-1])。

传送门:一篇写的容易理解的博客             2/21/2018 5:12:00 PM

-------------------------------------------------------分割线-----------------------------------------------------------

2/22/2018 10:27:00 PM

本来不想写详细一些,但是我发现其他的博客写的我越看越乱,实在是受不了了。

当然我自己写的也乱七八糟,但是我自己能看懂啊。

这里说dp思想的(ST),RMQ就是利用二进制倍增的思想,对数据进行最值比较。关于倍增的思想,传送门:小白兔

该算法通过将数据进行类似二分的操作,将数据进行比较。说的乱七八糟,不如直接解释样例来的实际。

先贴代码:

 void ST(){
for(int i=;i<=n;i++)
mm[i][]=mi[i][]=a[i];
for(int j=;(<<j)<=n;j++){
for(int i=;i+(<<j)-<=n;i++){
mm[i][j]=max(mm[i][j-],mm[i+(<<(j-))][j-]);
mi[i][j]=min(mi[i][j-],mi[i+(<<(j-))][j-]);
}
}
}

还是用其他题解的样例,我用这个推的。

样例3 2 4 5 6 8 1 2 9 7

首先应该知道1<<n是什么东西,位运算,就是左移位,想一下什么时候二进制的能向左移一位,当然是进位了,怎么才能进位啊,就是乘个2才能进位啊。

就是这个意思,1<<0是1,我智障,一开始当成2,我说怎么越推越不对。。。(T▽T)

开始咸鱼行动(只推一部分,讲道理,自己手推一遍就能明白,手推一遍还不懂的,就真的是过分了,就比我还智障了,我是最智障的)

一开始的时候就是比较自己,不管最大还是最小肯定都是自己,mm[1][0]=3,mm[2][0]=2,mm[3][0]=4。。。所以直接进行下一步。只推求最大值的(最小值也一样)

mm[1][1]=max(mm[1][0],mm[1+(1<<0)][0])=max([1][0],mm[1+1][0])=max([1][0],mm[2][0])==>max(3,2)=3;

mm[2][1]=max(mm[2][0],mm[2+(1<<0)][0])=max([2][0],mm[2+1][0])=max([2][0],mm[3][0])==>max(2,4)=4;

mm[3][1]=max(mm[3][0],mm[3+(1<<0)][0])=max([3][0],mm[3+1][0])=max([3][0],mm[4][0])==>max(4,5)=5;

mm[1][2]=max(mm[1][1],mm[1+2][1])=max(mm[1][1],mm[3][1])==>max(3,2,4,5)=5;

mm[2][2]=max(mm[2][1],mm[2+2][1])=max(mm[2][1],mm[4][1])==>max(2,4,5,6)=6;

                                                      max(4,5,6,8)=8;

max(5,6,8,1)=8;

max(6,8,1,2)=8;

接下来的mm[1][3]之类的也是这种操作,其实就是比较8个数的最值了(并不是真的比较8个数,而是通过前面假装比较4个数的得出来的,都是动态规划直接用上一个状态的数据得出来的)中间重复的一部分就直接省略过去了,这里就会省很多时间,这就是算法的美丽所在啊,所有能节省时间的算法都是无敌的。

这个操作是神操作,就是通过这种操作进行倍增的比较,也是动态规划美丽的地方(。◕ᴗ◕。)(仔细看看橙色的地方就懂了)。

将中间重复的2和4的比较就省略过去了(因为没必要),自己多推几个就明白了(懒是没用的),不能只会用,还要知道为什么这个可以这样用。

就酱,满足~ing

接下来是怎么找区间的最值呢?这里就好理解了。就是将要比较的区间分成两部分,通过状态转移就得出来。首先先算一下最多能2的多少次方满足区间长度,然后按这个长度将区间分开。

还是那个例子 3 2 4 5 6 8 1 2 9 7

假设我要找区间1--6的最大值,首先先算一下,1<<2就是2的平方=4的长度不会超过6-1+1=5,1<<3就是8了,不可以。所以就是找从第一个数开始的前4个数的最值和从6开始的倒着数4个数的最值的比较。

(本质上还是dp的思想,状态转移)就是max(3,2,4,5)和max(4,5,6,8)的比较。

解释的这么详细了,应该可以了。我要喊翠花了。

开始上菜。

Balanced Lineup
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 58952   Accepted: 27598
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 John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

Input

Line 1: Two space-separated integers, N and Q
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i 
Lines N+2..N+Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.

Output

Lines 1..Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0

Source

 
 
题目意思就是奶牛,从区间里找最大值和最小值的差。
以前用线段树写过,但是现在感觉还是RMQ比较好(代码短啊,哈哈哈)
 
贴一下RMQ的代码:
 #include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=*+;
const int maxm=;
int a[maxn],mm[maxn][maxm],mi[maxn][maxm];
int n,m;
void ST(){
for(int i=;i<=n;i++)
mm[i][]=mi[i][]=a[i];
for(int j=;(<<j)<=n;j++){
for(int i=;i+(<<j)-<=n;i++){
mm[i][j]=max(mm[i][j-],mm[i+(<<(j-))][j-]);
mi[i][j]=min(mi[i][j-],mi[i+(<<(j-))][j-]);
}
}
}
int RMQ(int l,int r){
int k=;
while((<<(k+))<=r-l+)k++;
int ans1=max(mm[l][k],mm[r-(<<k)+][k]);
int ans2=min(mi[l][k],mi[r-(<<k)+][k]);
return ans1-ans2;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
ST();
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",RMQ(l,r));
}
return ;
}

OK啦,溜了,进行下一步。

Go,进击吧,看我咸鱼突刺!!!(〃'▽'〃)

POJ 3264.Balanced Lineup-RMQ(ST)详解的更多相关文章

  1. POJ 3264 Balanced Lineup RMQ ST算法

    题意:有n头牛,编号从1到n,每头牛的身高已知.现有q次询问,每次询问给出a,b两个数.要求给出编号在a与b之间牛身高的最大值与最小值之差. 思路:标准的RMQ问题. RMQ问题是求给定区间内的最值问 ...

  2. Poj 3264 Balanced Lineup RMQ模板

    题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...

  3. POJ 3264 Balanced Lineup 【ST表 静态RMQ】

    传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total S ...

  4. poj 3264 Balanced Lineup (RMQ)

    /******************************************************* 题目: Balanced Lineup(poj 3264) 链接: http://po ...

  5. POJ - 3264 Balanced Lineup (RMQ问题求区间最值)

    RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就 ...

  6. poj 3264 Balanced Lineup (RMQ算法 模板题)

    RMQ支持操作: Query(L, R):  计算Min{a[L],a[L+1], a[R]}. 预处理时间是O(nlogn), 查询只需 O(1). RMQ问题 用于求给定区间内的最大值/最小值问题 ...

  7. POJ 3264 Balanced Lineup(ST模板)

    链接:http://poj.org/problem?id=3264 题意:给n个数,求一段区间L,R的最大值 - 最小值,Q次询问 思路:ST表模板,预处理区间最值,O(1)复杂度询问 AC代码: # ...

  8. POJ 3264 Balanced Lineup -- RMQ或线段树

    一段区间的最值问题,用线段树或RMQ皆可.两种代码都贴上:又是空间换时间.. RMQ 解法:(8168KB 1625ms) #include <iostream> #include < ...

  9. poj 3264 Balanced Lineup(RMQ裸题)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 43168   Accepted: 20276 ...

  10. POJ 3264 Balanced Lineup(RMQ)

    点我看题目 题意 :N头奶牛,Q次询问,然后给你每一头奶牛的身高,每一次询问都给你两个数,x y,代表着从x位置上的奶牛到y位置上的奶牛身高最高的和最矮的相差多少. 思路 : 刚好符合RMQ的那个求区 ...

随机推荐

  1. UIView和CALayer是什么关系?

    UIView显示在屏幕上归功于CALayer,通过调用drawRect方法来渲染自身的内容,调节CALayer属性可以调整UIView的外观,UIView继承自UIResponder,比起CALaye ...

  2. 《Cracking the Coding Interview》——第3章:栈和队列——题目7

    2014-03-19 03:20 题目:实现一个包含阿猫阿狗的先入先出队列,我要猫就给我一只来的最早的猫,要狗就给我一只来的最早的狗,随便要就给我一只来的最早的宠物.建议用链表实现. 解法:单链表可以 ...

  3. 《Cracking the Coding Interview》——第1章:数组和字符串——题目3

    2014-03-18 01:32 题目:对于两个字符串,判断它们是否是Anagrams. 解法:统计俩单词字母构成是否相同即可. 代码: // 1.3 Given two strings, write ...

  4. 【Max Points on a Line 】cpp

    题目: Given n points on a 2D plane, find the maximum number of points that lie on the same straight li ...

  5. mysql一机多实例安装记录

    因为想研究mycat,所以需要安装多个mysql实例进行研究.限于没有多于计算机,只能在本机安装了.通过mysql文档,自己琢磨着安装成功! 目录结构如下: 其中one和two文件夹用来模拟数据库分库 ...

  6. Kotlin将Realm提升到更高层次

    作者:Víctor Manuel Pineda 时间:Feb 14, 2017 原文链接:https://antonioleiva.com/kotlin-realm-extensions/ 当有人问我 ...

  7. python 读取数据库中文内容显示一堆问号

    需要在连接数据库时 设置编码格式 def select_db(self,db_name): self.conn = MySQLdb.connect( host = self.ip, port = se ...

  8. 团队冲刺Alpha(八)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  9. 团队Alpha版本(七)冲刺

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  10. hexo 添加标签

    --- title: title #文章標題 date: 2016-06-01 23:47:44 #文章生成時間 categories: "Hexo教程" #文章分類目錄 可以省略 ...