题意:有n头牛,编号从1到n,每头牛的身高已知。现有q次询问,每次询问给出a,b两个数。要求给出编号在a与b之间牛身高的最大值与最小值之差。

思路:标准的RMQ问题。

RMQ问题是求给定区间内的最值问题。当询问量巨大时,最朴素算法必然超时。解决RMQ比较优秀的算法有ST算法。其预处理时间复杂度为O(nlogn),询问的时间复杂度为O(1)。

ST的思想如下:

假设num数组中的数据从第0位开始存储。

用两个二维数组tmax,tmin分别求区间最大与最小值。ST的关键是数组区间的分割。tmax和tmin的下标是一致的,暂且拿tmax举例。

预处理:

预处理阶段运用的是DP的思想。tmax[i][j]内的值为区间[i, i + 2^j - 1]内的最大值。可以方便地理解为:第一个下标i为区间的开始位置,第二个坐标j表示区间的长度(只不过长度为指数形式)。如tmax[2][1]表示的是区间[2, 3]的最大值,tmax[2][2]表示的是区间[2, 5]的最大值。

而区间[i, i + 2^j - 1]可拆成[i, i + 2^(j - 1) - 1]和[i + 2^(j - 1), i + 2^j - 1]两个子区间。因此要计算tmax[i][j]的值,则有tmax[i][j] = max(tmax[i][j-1], tmax[i+2^(j-1)][j-1])。而所有递推的最初值tmax[i][0] = num[i]。对于tmin数组,下标的表示规则是相同的。

查询:

预处理进行完之后,可以进行查询。查询的复杂度为O(1)。

假设要查询区间[i, j]内的最大值。

首先第一步,先计算出一个整数k,k为满足表达式i + 2^k - 1 <= j 的最大整数。

然后将区间[i, j]分成两个部分重叠的子区间:[i, i + 2^k - 1]与[j - 2^k + 1, j]。

而tmax[i][k] 与tmax[j-2^k+1][k]中在预处理阶段便已计算出了结果,此时只需要输出两者中的较大者即可。

其他细节请看代码。

 #include<stdio.h>
#include<math.h>
#include<algorithm>
#define maxn 50020
using namespace std; int cow[maxn], tmax[maxn][], tmin[maxn][];
void st(int n)
{
int k = (int)(log((double)n) / log(2.0));
for (int i = ; i < n; i++)
tmin[i][] = tmax[i][] = cow[i];//递推的初值
for (int j = ; j <= k; j++)
for (int i = ; i + ( << j) - < n; i++)
{
int m = i + ( << (j - ));//求出中间值
tmax[i][j] = max(tmax[i][j-], tmax[m][j-]);
tmin[i][j] = min(tmin[i][j-], tmin[m][j-]);
}
}
//查询i和j之间的最值,注意i是从0开始的
void rmq(int i, int j)
{
int k = (int)(log(double(j - i + )) / log(2.0));
int t1 = max(tmax[i][k], tmax[j-(<<k)+][k]);
int t2 = min(tmin[i][k], tmin[j-(<<k)+][k]);
printf("%d\n",t1 - t2);
}
int main()
{
int n, q;
//freopen("data.in", "r", stdin);
scanf("%d%d",&n,&q);
for (int i = ; i < n; i++) scanf("%d",&cow[i]);
st(n);
while (q--)
{
int a, b;
scanf("%d%d",&a,&b);
rmq(a - , b - );//st算法从第0位开始,因此需要减一
}
return ;
}

POJ 3264 Balanced Lineup RMQ ST算法的更多相关文章

  1. Poj 3264 Balanced Lineup RMQ模板

    题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...

  2. POJ 3264 Balanced Lineup 【ST表 静态RMQ】

    传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total S ...

  3. poj 3264 Balanced Lineup (RMQ)

    /******************************************************* 题目: Balanced Lineup(poj 3264) 链接: http://po ...

  4. [POJ3264]Balanced Lineup(RMQ, ST算法)

    题目链接:http://poj.org/problem?id=3264 典型RMQ,这道题被我鞭尸了三遍也是醉了…这回用新学的st算法. st算法本身是一个区间dp,利用的性质就是相邻两个区间的最值的 ...

  5. POJ - 3264 Balanced Lineup (RMQ问题求区间最值)

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

  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(ST模板)

    链接:http://poj.org/problem?id=3264 题意:给n个数,求一段区间L,R的最大值 - 最小值,Q次询问 思路:ST表模板,预处理区间最值,O(1)复杂度询问 AC代码: # ...

  8. POJ 3264 Balanced Lineup -- RMQ或线段树

    一段区间的最值问题,用线段树或RMQ皆可.两种代码都贴上:又是空间换时间.. RMQ 解法:(8168KB 1625ms) #include <iostream> #include < ...

  9. [POJ] 3264 Balanced Lineup [ST算法]

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34306   Accepted: 16137 ...

随机推荐

  1. 倍增 - 强制在线的LCA

    LCA 描述 给一棵有根树,以及一些询问,每次询问树上的 2 个节点 A.B,求它们的最近公共祖先. !强制在线! 输入 第一行一个整数 N. 接下来 N 个数,第 i 个数 F i 表示 i 的父亲 ...

  2. 【Remove Nth Node From End of List】cpp

    题目: Given a linked list, remove the nth node from the end of list and return its head. For example, ...

  3. leetcode 【 Convert Sorted List to Binary Search Tree 】python 实现

    题目: Given a singly linked list where elements are sorted in ascending order, convert it to a height ...

  4. MFC深入浅出读书笔记第二部分2

    第七章  MFC骨干程序 所谓骨干程序就是指有AppWizard生成的MFC程序.如下图的层次关系是程序中常用的几个类,一定要熟记于心. 1 Document/View应用程序 CDocument存放 ...

  5. Boost入门

    [转载网友转载的 不过不知道原作者地址] Boost入门向导 简介:boost是一套开源的.高度可移植的C++模板库.它由C++标准委员发起,且里面很多组件有望成为下一代的C++标准库,其地位将会与S ...

  6. URL 传参中需要处理的特殊字符

    例如实际请求URL如下: http://www.douwansha.com/mdeditor?data=[{"address":null,"name":&quo ...

  7. asp.net允许跨域访问

    C# ASP.NET MVC 配置允许跨域访问 在web.config文件中的 system.webServer 节点下 增加如下配置 <httpProtocol> <customH ...

  8. 【转】Unity3D 射线Ray实现点击拾取

    游戏中经常会有鼠标移动到某个对象上来拾取它的功能,我们可以用Unity3D中的射线Ray实现这一效果.原理是在我们鼠标的位置,从屏幕射出一条射向世界空间的射线,当这条射线碰撞到我们需要拾取的对象时,我 ...

  9. POJ 2376:Cleaning Shifts(贪心)

    题目大意:有n个奶牛,他们负责在长为t个时间点的时间内值班,每个时间点至少有一个在值班,每个奶牛有一段空闲时间可以值班,求满足要求所需最少奶牛数量,无法满足则输出-1. 分析: 将奶牛空闲时间段看成线 ...

  10. eclipse快捷键补全

    Eclipse中 补全快捷键 默认Alt+/ 但是每个人习惯有所不同 我需要来修改自己熟悉的快捷键 windows->preferences->General->keys将Conte ...