题意:有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. ADO之密码验证--3次错误就锁定『改进』

    这里使用了SqlHelper,简化程序 自己写一个SqlHelper,把数据库的连接等都写到里面去. 首先把连接字符串添加到配置文件里去,右键解决方案-->添加新建项-->选择应用程序配置 ...

  2. idea使用maven逆向mybitis的文件

    引用自 http://blog.csdn.net/for_my_life/article/details/51228098 本文介绍一下用Maven工具如何生成Mybatis的代码及映射的文件. 一. ...

  3. Unity3D_异步加载场景(进度条)

    创建两个场景:现在的场景“NowScene”,要加载的场景“LoadScene”: “NowScene”如图所示,“LoadScene”任意: 创建脚本“AsyncLoadScene”,复制如下代码, ...

  4. redhat linux 7.4关闭透明大页

    每一步: 在GRUB_CMDLINE_LINUX加入选项 transparent_hugepage=never echo 'GRUB_CMDLINE_LINUX="transparent_h ...

  5. ubuntu--基础环境瞎搞集合

    安装ubuntu系统后有很多东西需要自己瞎搞一下,这里把一些瞎搞的过程记录在这里,方便以后重新装系统后重新配置. 一.安装. 可以在windows下制作启动盘(软碟通),然后开机u盘启动即可安装,预留 ...

  6. 【神题】AtCoder 028 C Min Cost Cycle

    TO BE DONE 思维题 十分巧妙的转化

  7. HDU 1392 Surround the Trees(凸包入门)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  8. 练级(train)

    练级(train) 试题描述 cxm 在迷宫中练级.迷宫可以看成一个有向图,有向图的每个边上都有怪物.通过每条边并消灭怪物需要花费 \(1\) 单位时间.消灭一个怪物可以得到一定数量的经验值.怪物被消 ...

  9. python数据结构之字典

    1.python字典的定义 1.用大括号{},以逗号分隔每个键值对,键与值之间用冒号连接 2.键:需要不可变的数据结构,值可以是任意的数据对象 3.字典是无序的,键在字典中必须是唯一,在字典中取值的方 ...

  10. Struts框架详解

    1.Struts应用框架介绍 (1)框架 框架最简单的形式是指已开发过并已测试过的软件的程序块,这些程序块可以在多个软件开发工程中重用.框架提供了一个概括的体系结构模版,可以用这个模板来构建特定领域中 ...