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. 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 ≤ ABN), 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
///RMQ问题之Sparse_Table算法  模板 区间最大最小值

#include <math.h>
#include <stdio.h>
#include <iostream> #define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b using namespace std;
const int N=;
int n,Q,c[N],a,b;
int dp_max[N][]; ///33足够用 2^32 是 int
int dp_min[N][]; void Init()
{
for(int i=; i<=n; i++)
dp_max[i][] = dp_min[i][] = c[i];
double limit = log(n)/log(2.0);
for(int j=; j<=(int)limit; j++)
for(int i=; i+(<<j)-<=n; i++)
{
dp_max[i][j] = max(dp_max[i][j-],dp_max[i+(<<(j-))][j-]);
dp_min[i][j] = min(dp_min[i][j-],dp_min[i+(<<(j-))][j-]);
}
}
int Get_Max(int a,int b)
{
int k = (int)(log(b-a+)/log(2.0));
return max(dp_max[a][k],dp_max[b-(<<k)+][k]);
}
int Get_Min(int a,int b)
{
int k = (int)(log(b-a+)/log(2.0));
return min(dp_min[a][k],dp_min[b-(<<k)+][k]);
}
int main()
{
scanf("%d%d",&n,&Q);
for(int i=; i<=n; i++)
scanf("%d",&c[i]);
Init();
while(Q--)
{
scanf("%d%d",&a,&b);
printf("%d\n",Get_Max(a,b)-Get_Min(a,b));
}
return ;
}

RMQ问题,全名(Range Minimum/Maximum Query),是求给定区间中的最值问题。

主要方法及复杂度如下:

1、朴素(即搜索),O(n)-O(qn) online。

2、线段树,O(n)-O(qlogn) online。

3、Sparse_Table(实质是动态规划),O(nlogn)-O(1) online。

4、RMQ标准算法:先规约成LCA(Lowest Common Ancestor),再规约成约束RMQ,O(n)-O(1) online。

ST算法可以在O(nlogn)的预处理以后实现O(1)的查询效率,从而解决查询次数很多(如大于100万)的RMQ问题。

首先,是预处理。预处理是采用dp的思想,我们用f[i][j]表示区间[i,i+2^j-1]中的最大值(即从i开始,长度为2^j的闭区间)。

开始时,f[i][0]一定等于num[i]。好了,初始值找到了,下面是状态转移方程:

f[i][j]=max(f[i][j-1],f[i+2^(j-1)][j-1])。即把[i,i+2^j-1]区间分成两部分[i,i+2^(j-1)-1]和[i+2^(j-1),i+2^(j-1)+2^(j-1)-1],正好和原区间一致。

有了初始值和转移方程,我们可以自底向上递推出所有的f[i][j]的值。

对于边界,还要注意一点。由于区间长度最大为n,所以二维边界最大为log(n)/log(2.0);

一维边界只要满足对于每个起始点,都可以有长度找到n就行了,也就是让i+2^j-1<=n就好了。

然后就是查询了。假设要查询区间[a,b]的最大值,由于区间的长度很可能不是2的整数幂,所以我们要把区间划分为长度为2的整数幂的两部分,而且
这两个区间的并集必须是[a,b]。为了实现这个方案,我们需要先求出一个最大的k,使得2^k<=(b-a+1),这样就可以把区间分成两部分
[a,a+2^k-1]和[b-2^k+1,b],使他们既能不超过a,b区间的范围,又能把区间全部覆盖。于是,[a,b]区间的最大值就等于上述两个
区间的最大值中最大的那个。(有点绕)

poj 3264 区间最大最小值 RMQ问题之Sparse_Table算法的更多相关文章

  1. POJ 3264 区间最大最小值Sparse_Table算法

    题目链接:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total ...

  2. POJ 3264 Balanced Lineup(RMQ)

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

  3. 【RMQ】【Sparse_Table算法】

    摘自网友,具体哪个忘记了,抱歉~ 定义: RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题: 对于长度为n的数列A,回答若干询问RMQ(A,i,j) ...

  4. POJ 3264 Balanced Lineup 简单RMQ

    题目:http://poj.org/problem?id=3264 给定一段区间,求其中最大值与最小值的差. #include <stdio.h> #include <algorit ...

  5. (简单) POJ 3264 Balanced Lineup,RMQ。

    Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same ...

  6. POJ 3171 区间覆盖最小值&&线段树优化dp

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4715   Accepted: 1590 D ...

  7. poj 3264 Balanced Lineup(RMQ裸题)

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

  8. 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分析:标 ...

  9. POJ - 3264 线段树模板题 询问区间最大最小值

    这是线段树的一个模板题,给出一串数字,然后询问区间的最大最小值. 这个其实很好办,只需把线段树的节点给出两个权值,一个是区间的最小值,一个是区间的最大值,初始化为负无穷和正无穷,然后通过不断地输入节点 ...

随机推荐

  1. oracle主键修改&设置某一字段可以为null

    1.oracle主键修改 1.1)首先查看需要修改的表的主键名,默认的情况下,数据库会自动分配 select * from user_cons_columns where table_name='表名 ...

  2. BZOJ1977或洛谷4180 [BJWC2010]次小生成树

    一道LCA+生成树 BZOJ原题链接 洛谷原题链接 细节挺多,我调了半天..累炸.. 回到正题,我们先求出随便一棵最小生成树(设边权和为\(s\)),然后扫描剩下所有边,设扫到的边的两端点为\(x,y ...

  3. 设计师别浪费时间啦,快来试试这款Sketch标注插件吧

    随着移动互联网的快速发展,用户的需求也在不断地增大,这对产品经理还有设计师的考验是越来越大.市场环境的变化让我们深信为快不破,但是一个产品的产出需要各个环节的紧密配合,但往往在产品输出过程中,由于分工 ...

  4. javascript 事件流的应用之 addEventListener

    原始需求:防止按钮短时间内高频率触发点击事件,由于重复提交导致的业务异常. 图: demo: <!DOCTYPE html> <html lang="en" di ...

  5. Gym - 100735E Restore

    E - Restore 题意:输入一个n,输入一个对角线空缺(为0)的n*n的矩阵,要求每一行每一列和对角线的和相同,输出完整的矩阵. 解法:设每一行的和都是sum,用一个h[]数组存每一行的和.则可 ...

  6. hibernate 的evict 和clear

    摘自百度知道:http://zhidao.baidu.com/question/63663640.html 问: 先创建一个Student,然后调用session.save方法,然后再调用evict方 ...

  7. Mac osx 启用和关闭root用户

    设置->群组和用户->点击小

  8. PHP中=>是什么意思

    一般用在php数组键名与元素的连接符如:$arr = array('a'=>'123','b'=>'456'); foreach($arr as $key=>$val){//$key ...

  9. 2018.12.15 poj3415 Common Substrings(后缀自动机)

    传送门 后缀自动机基础题. 给两个字符串,让你求长度不小于kkk的公共子串的数量. 这题可以用后缀自动机解决废话 考虑对其中一个字串建出后缀自动机,然后用另一个在上面跑,注意到如果一个状态有贡献的话, ...

  10. Mybatis之动态构建SQL语句(转)

    https://www.cnblogs.com/zhangminghui/p/4903351.html