大致题意:
给出一列共n个数,m次询问。每次询问包括两个数a,b。输出区间[a,b]中最大值与最小值的差。
大致思路:
RMQ区间极值求法的模版题。
以下内容转自:http://www.cnblogs.com/cnjy/archive/2009/08/30/1556566.html
RMQ(Range Minimum/Maximum Query)问题:
RMQ问题是求给定区间中的最值问题。当然,最简单的算法是O(n)的,但是对于查询次数很多(设置多大100万次),O(n)的算法效率不够。可以用线段树将算法优化到O(logn)(在线段树中保存线段的最值)。不过,Sparse_Table算法才是最好的:它可以在O(nlogn)的预处理以后实现O(1)的查询效率。下面把Sparse Table算法分成预处理和查询两部分来说明(以求最小值为例)。
预处理:
预处理使用DP的思想,f(i, j)表示[i, i+2^j - 1]区间中的最小值,我们可以开辟一个数组专门来保存f(i, j)的值。
例如,f(0, 0)表示[0,0]之间的最小值,就是num[0], f(0, 2)表示[0, 3]之间的最小值, f(2, 4)表示[2, 17]之间的最小值
注意, 因为f(i, j)可以由f(i, j - 1)和f(i+2^(j-1), j-1)导出, 而递推的初值(所有的f(i, 0) = i)都是已知的
所以我们可以采用自底向上的算法递推地给出所有符合条件的f(i, j)的值。
查询:
假设要查询从m到n这一段的最小值, 那么我们先求出一个最大的k, 使得k满足2^k <(n - m + 1).
于是我们就可以把[m, n]分成两个(部分重叠的)长度为2^k的区间: [m, m+2^k-1], [n-2^k+1, n];
而我们之前已经求出了f(m, k)为[m, m+2^k-1]的最小值, f(n-2^k+1, k)为[n-2^k+1, n]的最小值
我们只要返回其中更小的那个, 就是我们想要的答案, 这个算法的时间复杂度是O(1)的.
例如, rmq(0, 11) = min(f(0, 3), f(4, 3))
由此我们要注意的是预处理f(i,j)中的j值只需要计算log(n+1)/log(2)即可,而i值我们也只需要计算到n-2^k+1即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int nMax= 50003;
int num[nMax],n;
int maxMap[nMax][20];
int minMap[nMax][20];
void maxRmq(){ //map(i, j)表示[i, i+2^j - 1]区间中的最值
int i,j;
for(i=1;i<=n;i++){
maxMap[i][0]=num[i];
}
for(j=1;j<=log((double)(n+1))/log(2.0);j++){
for(i=1;i+(1<<j)-1<=n;i++){
maxMap[i][j]=max(maxMap[i][j-1],maxMap[i+(1<<(j-1))][j-1]);
}
}
}
void minRmq(){
int i,j;
for(i=1;i<=n;i++){
minMap[i][0]=num[i];
}
for(j=1;j<=log((double)(n+1))/log(2.0);j++){
for(i=1;i+(1<<j)-1<=n;i++){
minMap[i][j]=min(minMap[i][j-1],minMap[i+(1<<(j-1))][j-1]);
}
}
}
int askMax(int a,int b){
if(a>b)swap(a,b);
int k =(int)(log((double)(b-a+1))/log(2.0));
return max(maxMap[a][k],maxMap[b-(1<<k)+1][k]);
}
int askMin(int a,int b){
if(a>b)swap(a,b);
int k=(int)(log((double)(b-a+1))/log(2.0));
return min(minMap[a][k],minMap[b-(1<<k)+1][k]);
}
int main(){
int m,i,j,a,b;
while(scanf("%d%d",&n,&m)!=EOF){
for(i=1;i<=n;i++)scanf("%d",&num[i]);
maxRmq();
minRmq();
while(m--){
scanf("%d%d",&a,&b);
printf("%d\n",askMax(a,b)-askMin(a,b));
}
}
return 0;
}
分享到:
相关推荐
### RMQ与LCA:最近公共祖先解析及解法 #### 一、引言 在计算机科学领域,尤其是在算法设计中,“最近公共祖先”(LCA, Least Common Ancestor)和“区间最小值查询”(RMQ, Range Minimum Query)是两个非常重要...
rmq-docker-win docker build -t gsxsolutions/rmq:3.5.4 -f .\Dockerfile.3.5.4 . docker build -t gsxsolutions/rmq:3.7.4 -f .\Dockerfile.3.7.4 . docker build -t gsxsolutions/rmq:3.7.5 -f .\Dockerfile....
RMQ 动画 这是用于创建文档中说明的动画的应用程序。 这个 repo 是一个简单的应用程序,用于说明 RMQ 可用的动画: rmq(my_view).animations.fade_in rmq(my_view).animations.fade_out rmq(my_view).animations....
* RMQ:例如 poj3264、poj3368。 * 并查集的高级应用:例如 poj1703、poj2492。 * KMP 算法:例如 poj1961、poj2406。 4. 搜索: * 最优化剪枝和可行性剪枝。 * 搜索的技巧和优化:例如 poj3411、poj1724。 *...
RMQ.io 您是否要构建可靠且易于编码的连接服务?Rmq.io的任务rmq.io的任务是使RabbitMQ的发布订阅变得容易1,2,3基本原理一个可靠且简单的pubsub并不容易找到。 RabbitMQ是功能强大的消息队列,它具有许多功能,对于...
POJ 3264 Balanced Lineup和POJ 2823 Sliding Window问题则分别展示了RMQ问题在不同场景下的应用。 总的来说,RMQ和LCA是ACM中重要且实用的数据结构问题,它们涉及到动态规划、线段树、Sparse Table、并查集等多种...
简单的 Rabbit MQ 示例 一个使用 Erlang 客户端库的非常简单的 Rabbit MQ 示例 ... 克隆 rmq_simple cd rmq_simple 使 RABBITMQ_VERSION={Version} 依赖 编译 跑起来 享受 :grinning_face_with_smiling_eyes: !
* RMQ:POJ3264、POJ3368 * 并查集的高级应用:POJ1703、POJ2492 * KMP算法:POJ1961、POJ2406 * 左偏树(可合并堆) 四、搜索 * 最优化剪枝和可行性剪枝 * 较为复杂的动态规划:POJ1191、POJ1054、POJ3280、POJ...
- RMQ(区间查询):如`poj3264, poj3368`。 - 并查集的高级应用:如`poj1703, poj2492`。 - **搜索** - 最优化剪枝和可行性剪枝:如`poj3411, poj1724`。 - **动态规划** - 复杂的动态规划:如`poj1191, poj...
4. **RMQ(Range Minimum Query)**(如poj3264, poj3368):快速查询区间内的最小值,适用于数据压缩、图像处理等领域。 5. **后缀树/后缀数组**(如poj1703, 2492):用于字符串的高效处理,适用于文本索引、生物...
ACM常用算法及其相应的练习题 ... + poj3264, poj3368 * 并查集的高级应用 + poj1703, poj2492 * KMP算法 + poj1961, poj2406 四、搜索 * 最优化剪枝和可行性剪枝 * 搜索的技巧和优化 + poj3411, poj1724
4. **区间查询**:如RMQ问题(poj3264, poj3368)。 5. **字符串匹配**:如KMP算法(poj1961, poj2406)。 ### 十三、进阶算法 1. **组合优化**:如割平面法、分支定界法等(poj3411, poj1724)。 2. **近似算法**...
在POJ3264中,要求找出牛的身高差的最大值,通过构建RMQ数据结构,可以快速找到区间内的最大值和最小值,两者相减即可得到身高差。RMQ可以通过各种方法实现,如ST(Sqrt-Decomposition)分解、Sparse Table或Fenwick...
标题中的"rmq.rar_RMQ_RMQ algorithm_RMQ c++"表明我们将讨论RMQ算法以及其在C++编程语言中的实现。 **RMQ问题定义** RMQ问题的定义是这样的:给定一个长度为n的数列A,我们需要处理多个查询,每个查询询问数列A中...
已完成:天真RMQ,更快RMQ(使用nlogn稀疏表) 待办事项:执行±1 RMQ 天真的RMQ输出: (1(2(4..)(5..))(3(6..)(7..))) indexs : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, values : [1, 2, 4, 2, 5, 2, 1, 3,...
### RMQ(Range Minimum/Maximum Query)详解 #### 引言 在计算机科学与算法设计领域,RMQ问题,即范围最小/最大查询问题,是一个经典的动态规划与数据结构问题。它涉及到对一段连续的数据进行快速查询,找到该区间...
2015_ble_to_rmq ble_to_rmq sample说明: 将此程式编译过的jar档放到respberry pi上执行,可以搜寻附近的BLE Device并与之连接,将透过dongle送到respberry pi的ble讯息印出来。
标题和描述中的“poj各种分类”主要指向的是在POJ(Peking University Online Judge)平台上,根据解题策略和算法类型对题目进行的分类。POJ作为一个知名的在线编程平台,提供了大量的算法练习题,适合从初学者到...
poj1035、poj3080等训练了串的操作,poj2388、poj2299等则涉及排序问题,poj2524、poj1611等是并查集的实例,poj3349、poj3274等展示了哈希表和二分查找,poj3253是哈夫曼树的题目,poj2442和poj1442则关于堆。...
- 示例题目:poj3264, poj3368 - **后缀数组** - 示例题目:poj1703, poj2492 - **KMP算法** - 示例题目:poj1961, poj2406 #### 高级动态规划 1. **矩阵乘法** - 示例题目:poj1191, poj1054, poj3280, poj...