POJ 3264 -----RMQ问题

Balanced Lineup

Time Limit: 5000 MS Memory Limit: 0 KB

64-bit integer IO format: %I64d , %I64u Java class name: Main

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

USACO 2007 January Silver

1.

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

2.

首先是预处理,用动态规划(DP)解决。设A[i]是要求区间最值的数列,F[i, j]表示从第i个数起连续2^j个数中的最大值。例如数列3 2 4 5 6 8 1 2 9 7,F[1,0]表示第1个数起,长度为2^0=1的最大值,其实就是3这个数。 F[1,2]=5,F[1,3]=8,F[2,0]=2,F[2,1]=4……从这里可以看出F[i,0]其实就等于A[i]。这样,DP的状态、初值都已经有了,剩下的就是状态转移方程(关键)。我们把F[i,j]平均分成两段(因为f[i,j]一定是偶数个数字),从i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1为一段(长度都为2^(j-1))。用上例说明,当i=1,j=3时就是3,2,4,5 和 6,8,1,2这两段。F[i,j]就是这两段的最大值中的最大值。于是我们得到了动态规划方程F[i, j]=max(F[i,j-1], F[i + 2^(j-1),j-1])。

然后是查询。取k=[log2(j-i+1)],则有:RMQ(A, i, j)=min{F[i,k],F[j-2^k+1,k]}。 举例说明,要求区间[2,8]的最大值,就要把它分成[2,5]和[5,8]两个区间,因为这两个区间的最大值我们可以直接由f[2,2]和f[5,2]得到。

3 代码

#include<stdio.h>
#include<math.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50005;

int d1[maxn][20];
int d2[maxn][20];
int a[maxn];
int n,m;

void RMQ_init()
{
for(int i=0;i<n;i++)
{
d1[i][0]=a[i];
d2[i][0]=a[i];
}
for(int j=1;(1<<j)<=n;j++)
for(int i=0;i+(1<<j)-1<n;i++)
{

d1[i][j]=min(d1[i][j-1],d1[i+(1<<(j-1))][j-1]);
d2[i][j]=max(d2[i][j-1],d2[i+(1<<(j-1))][j-1]);
}
}

int rmq_min(int L,int R)
{

int k=0;
while((1<<(k+1))<=R-L+1)
k++;
return min(d1[L][k],d1[R-(1<<k)+1][k]);
}
int rmq_max(int L,int R)
{

int k=0;
while((1<<(k+1))<=R-L+1)
k++;
return max(d2[L][k],d2[R-(1<<k)+1][k]);
}

int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
RMQ_init();
for(int i=0;i<m;i++)
{
int L,R;
scanf("%d%d",&L,&R);
L--,R--;
printf("%d\n",rmq_max(L,R)-rmq_min(L,R));
}

}
return 0;
}

时间: 2024-10-10 15:04:07

POJ 3264 -----RMQ问题的相关文章

POJ 3264 RMQ Spare Table算法

今天下午大帝讲的,我以前也不懂,所以也就跟着学学了,把中间的那个状态转移方程学错了好几次,于是就wa了 好几发. #include<iostream> #include<cstdio> #include<algorithm> #define maxn 200010 using namespace std; int a[maxn],m,n,b[maxn],fl[maxn][50],fr[maxn][50]; void solve() { b[1]=0;//其实就是用来计算

POJ 3264 RMQ裸题

POJ 3264 题意:n个数,问a[i]与a[j]间最大值与最小值之差. 总结:看了博客,记下了模板,但有些地方还是不太理解. #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #

poj 3264(RMQ或者线段树)

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 42929   Accepted: 20184 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 Joh

poj 3264 RMQ 水题

题意:找到一段数字里最大值和最小值的差 水题 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=550; 9 const int INF=0x3f3f3f3f; 10 in

poj 3264 RMQ

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 44075   Accepted: 20687 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 Joh

POJ 3264 RMQ水题

题目大意就是有很多牛.告诉你每只牛的高度.然后有很多个询问.输出该区间内的最大身高差.也就是用RMQ求最大值最小值.貌似还可以用线段树.然而,我还不会线段树.....T_T 可能是太多组数据了.cin和cout会TLE.换成scanf和printf就顺当的AC了....啦啦啦. RMQ还是只会用模板..T_T 附代码:#include<stdio.h>#include<string.h>#include<iostream>#include<math.h>#d

POJ 3264 RMQ问题 用dp解决

1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int N = 50010; 6 #define INF 0x3f3f3f3f 7 int maxn[N<<1][18] , minn[N<<1][18] , a[N]; 8 9 void build_dp(int n) 10 { 11 memset(maxn

poj 3264(模板RMQ)

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34488   Accepted: 16203 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 Joh

poj 3264 区间最大最小值 RMQ问题之Sparse_Table算法

Balanced Lineup Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order