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

ヾ(◍°∇°◍)ノ゙

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. USACO Section1.1 Friday the Thirteenth 解题报告

    friday解题报告 —— icedream61 博客园(转载请注明出处) -------------------------------------------------------------- ...

  2. leetcode 【 Linked List Cycle 】 python 实现

    题目: Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ...

  3. 了解JavaScript核心精髓(三)

    1.js判断对象是否存在属性. hasOwnProperty(‘property’)  判断原型属性是否存在. "property" in o;  判断原型属性和原型链属性是否存在 ...

  4. JMeter学习笔记(十一) 关于 CSV Data Set Config 的 Sharing mode 对取值的影响

    关于 CSV Data Set Config 的一些介绍之前已经梳理过了,可以参考: https://www.cnblogs.com/xiaoyu2018/p/10184127.html . 今天主要 ...

  5. 1.0 python-client以及ui自动化介绍

     appium的client-----捕获元素和对元素进行操作都是在client里面去写脚本实现的,client会将你写的python脚本发送到appium server上,然后appium serv ...

  6. Python学习-day19 django基础篇

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  7. cd,PATH,alias,man,快捷键

    5. cd命令cd 后面不加东西,就是进入到当前用户的家目录cd ~ 这里的~符号也表示用户的家目录cd - 切换到上一次所在的目录cd . .. 其中.表示当前目录, ..表示上一级目录注意区分绝对 ...

  8. 有许多部分没有在cgroup中显示啊,current/high/low/min等等

    没看见current/high/low/min 在cgroup中的显示内容

  9. Error: could not find java.dll 解决办法

    Error: could not find java.dll 问题: 安装配置Java环境变量后,在命令行中运行java -version进行测试时却出现下面的问题: Error: opening r ...

  10. 【bzoj4952】[Wf2017]Need for Speed 二分

    题目描述 已知$\sum\limits_{i=1}^n\frac{d_i}{s_i+c}=t$,求$c$ $(d_i>0,s_i+c>0)$ 输入 第一行包含两个整数n(1≤n≤1000) ...