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. POI设置EXCEL单元格格式为文本、小数、百分比、货币、日期、科学计数法和中文大写

    再读本篇文章之前,请先看我的前一篇文章,前一篇文章中有重点讲到POI设置EXCEL单元格格式为文本格式,剩下的设置小数.百分比.货币.日期.科学计数法和中文大写这些将在下面一一写出 以下将要介绍的每一 ...

  2. POJ 3069 Saruman&#39;s Army

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6688   Accepted: 3424 De ...

  3. iOS:网络编程中三个数据解析协议HTTP、XML、JSON的详细介绍

    网络编程:HTTP协议.XML数据协议.JSON数据协议: HTTP: 1.HTTP传输数据有四种方式:Get方式.Post方式.同步请求方式.异步请求方式. 说明:同步和异步请求方式在创建链接对象和 ...

  4. Visual Studio 2017各版本离线安装包获取以及安装教程

    系统:  windows 7旗舰版 前言: Visual Studio 2017版本与以往的2015.2013.2012版本不同,采用了新的模块化安装方法.微软官方也并未提供ISO镜像,作者根据官方提 ...

  5. CC+语言 struct 深层探索——CC + language struct deep exploration

    1        struct 的巨大作用 面对一个人的大型C/C++程序时,只看其对struct 的使用情况我们就可以对其编写者的编程经验进行评估.因为一个大型的C/C++程序,势必要涉及一些(甚至 ...

  6. mysql的正则表达式

    所谓正在表达式,就是通过模式去匹配一类字符串.MySQL支持的模式字符如下表所示: MySQL支持的模式字符 模式字符 含义 ^ 匹配字符串的开始部分 $ 匹配字符串的结束部分 . 匹配字符串中的任意 ...

  7. [ES6] 03. The let keyword -- 1

    var message = "Hi"; { var message = "Bye"; } console.log(message); //Bye The mes ...

  8. Python模块学习 ---- logging 日志记录

    许多应用程序中都会有日志模块,用于记录系统在运行过程中的一些关键信息,以便于对系统的运行状况进行跟踪.在.NET平台中,有非常著名的第三方开源日志组件log4net,c++中,有人们熟悉的log4cp ...

  9. Warning: cast to/from pointer from/to integer of different size

    将int变量转为(void*)时出现错误 error: cast to pointer from integer of different size [-Werror=int-to-pointer-c ...

  10. Java Executor 线程池