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

Time Limit: 5000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

Submit Status

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.. NQ+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

1.朴素(遍历): 复杂度O(n)-O(qn)。

2.线段树 :复杂度O(n)-O(qlogn)。

3.ST(Sparse Table)算法 :O(nlogn)-O(q)

说下ST算法,由于每一个查询仅仅有O(1)。在处理大量查询的时候有优势。

<1>.预处理(动态规划DP)

对A[i]数列,F[i][j] 表示从第i个数起连续2^j 中的最大值(DP的状态),能够看到,F[i][0] 表示的是A[i](DP的初始值)。

最后。状态转移方程是

F[i][j]=max(F[i][j-1],F[i+2^(j-1)][j-1])

<2>查询

若查询区间为(a。b),区间长度为b-a+1,取k=log2(b-a+1),则Max(a。b)=max(F[a][k]。F[b-2^k+1][k])。

1.ST算法

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std; const int MAXN = 50050; int mins[MAXN][20];
int maxs[MAXN][20]; void RMQ(int n)
{
for (int j = 1; (1 << j) <= n;j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
{
int p = (1 << (j - 1));
mins[i][j] = min(mins[i][j - 1], mins[i + p][j - 1]);
maxs[i][j] = max(maxs[i][j - 1], maxs[i + p][j - 1]);
}
} int queryMin(int l, int r)
{
int k = log((double)(r - l + 1))/log(2.0);
return min(mins[l][k], mins[r - (1 << k) + 1][k]);
} int queryMax(int l, int r)
{
int k = log((double)(r - l + 1))/log(2.0);
return max(maxs[l][k], maxs[r - (1 << k) + 1][k]);
} int main()
{
int n, q;
scanf("%d%d", &n, &q);
int num;
for (int i = 1; i <= n; i++)
{
scanf("%d", &num);
maxs[i][0] = mins[i][0] = num;
}
RMQ(n);
int a, b;
int ans;
for (int i = 0; i < q; i++)
{
scanf("%d%d", &a, &b);
ans= queryMax(a, b) - queryMin(a, b);
printf("%d\n", ans);
}
}

2.线段树

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b) using namespace std; const int MAXN = 50050; int num[MAXN]; struct node
{
int r;
int l;
int Max;
int Min;
}tree[3*MAXN]; void build(int l, int r, int i)
{
tree[i].l = l; tree[i].r = r;
if (l == r)
{
tree[i].Max = tree[i].Min = num[l];
return;
}
int m = (l + r) >> 1, ls = i << 1, rs = ls + 1;
build(l, m, ls);
build(m + 1, r, rs);
tree[i].Max = max(tree[rs].Max, tree[ls].Max);
tree[i].Min = min(tree[rs].Min, tree[ls].Min);
} int queryMax(int l, int r, int i)
{
if (tree[i].l == l&&tree[i].r == r)
return tree[i].Max;
int m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1;
if (r <= m) return queryMax(l, r, ls);
else if (l > m) return queryMax(l, r, rs);
else return max(queryMax(l, m, ls), queryMax(m + 1, r, rs));
} int queryMin(int l, int r, int i)
{
if (tree[i].l == l&&tree[i].r == r)
return tree[i].Min;
int m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1;
if (r <= m) return queryMin(l, r, ls);
else if (l > m) return queryMin(l, r, rs);
else return min(queryMin(l, m, ls), queryMin(m + 1, r, rs));
} int main()
{
int n, q;
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; i++)
scanf("%d", &num[i]);
build(1, n, 1);
int a, b;
int ans;
for (int i = 0; i < q; i++)
{
scanf("%d%d", &a, &b);
ans = queryMax(a, b, 1) - queryMin(a, b, 1);
printf("%d\n", ans);
}
}

參考了http://blog.csdn.net/niushuai666/article/details/6624672/

POJ - 3264 Balanced Lineup (RMQ问题求区间最值)的更多相关文章

  1. Poj 3264 Balanced Lineup RMQ模板

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

  2. poj 3264 Balanced Lineup (RMQ)

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

  3. poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】

    题目地址:http://poj.org/problem?id=3264 Sample Input 6 3 1 7 3 4 2 5 1 5 4 6 2 2 Sample Output 6 3 0分析:标 ...

  4. POJ 3264 Balanced Lineup 【线段树/区间最值差】

    Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 62103 Accepted: 29005 Cas ...

  5. POJ 3264 Balanced Lineup RMQ ST算法

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

  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 -- RMQ或线段树

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

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

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

  9. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

随机推荐

  1. iOS开源项目:FlatUIKit

    FlatUIKit是iOS中具有扁平化风格的UI(Flat UI)组件.FlatUIKit的设计灵感来源于Flat UI和Kyle Miller.FlatUIKit中的组件是通过扩展(category ...

  2. OpenCV学习(6) 文件和Mat之间的数据交换

          有时候为了便于调试算法,我们需要从文本文件或二进制文件中读取数据,并把数据放到相应的矩阵中去.我们通常可以通过下面的函数实现.   1.从二进制文件中读取数据.      新建一个txt文 ...

  3. Install Python+Django+Nginx+UWSGI

    一.软件环境: CentOS6.6_64bit 需要用到的软件: [root@django tools]# ll 总用量 33336 -rw-r--r-- 1 root root 7497785 3月 ...

  4. 作用JavaScript访问和操作数据库

    JS操作 Access 数据库 <SCRIPT LANGUAGE="JavaScript"> <!-- var filePath = location.href. ...

  5. (剑指Offer)面试题56:链表中环的入口结点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 1.哈希表 遍历整个链表,并将链表结点存入哈希表中(这里我们使用容器set),如果遍历到某个链表结点已经在set中,那么该点即为环的入口 ...

  6. leetCode 45.Jump Game II (跳跃游戏) 解题思路和方法

    Jump Game II Given an array of non-negative integers, you are initially positioned at the first inde ...

  7. angular中定义全局变量及全局变量的使用

    一个例子,定义了两个变量,并且把变量显示出来: <!DOCTYPE html> <html ng-app="myApp"> <head> < ...

  8. 使用Bundle进行VIM插件的管理

    http://www.oschina.net/p/vundle git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle ...

  9. MPMoviePlayerViewController 视频播放黑屏

    MPMoviePlayerViewController 视频播放黑屏 今天用视频做本地视频播放:使用 MPMoviePlayerViewController 老是出现黑屏: 结果发现是一个 很坑爹的问 ...

  10. js 函数节流throttle 函数去抖debounce

    1.函数节流throttle 通俗解释: 假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯: 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟: ...