博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 3264 区间最大最小值 RMQ问题之Sparse_Table算法
阅读量:5162 次
发布时间:2019-06-13

本文共 2351 字,大约阅读时间需要 7 分钟。

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 31734251 54 62 2

Sample Output

630
///RMQ问题之Sparse_Table算法  模板 区间最大最小值#include 
#include
#include
#define max(a,b) a>b?a:b#define min(a,b) a

 

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]区间的最大值就等于上述两个 区间的最大值中最大的那个。(有点绕)

转载于:https://www.cnblogs.com/zhangying/p/3906683.html

你可能感兴趣的文章
【BZOJ1911】【APIO2010】特别行动队(斜率优化,动态规划)
查看>>
min_25筛
查看>>
史上最强的美名腾智能起名成功发布
查看>>
C# 统计字符串出现的个数
查看>>
数据结构学习笔记1
查看>>
百度地图api2.0体验
查看>>
[转]失业的程序员(五):商战之前
查看>>
delphi数组之菜鸟篇
查看>>
node
查看>>
day01 Java基础
查看>>
Web开发应该注意的问题
查看>>
异常处理
查看>>
SSH2中实例化不了Action的一个原因
查看>>
EF,MVC相关项目请参见→
查看>>
依赖倒置原则(DIP)
查看>>
CV顶会 & CV顶刊
查看>>
HDFS常用命令
查看>>
图像处理与分析导论
查看>>
浅谈压缩感知(二十二):压缩感知重构算法之正则化正交匹配追踪(ROMP)
查看>>
二叉搜索树的后序遍历序列
查看>>