标签:
题目地址: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
分析:标准的模板题,可以用线段树写,但用RMQ-ST来写代码比较短。
每次输出区间【L, R】内最大值和最小值的差是多少。
注意一个地方,代码里面用到了log2()函数,但是我用包含<math.h>和<cmath>头文件的代码以C++的方式提交到POJ反馈是编译错误。
改成g++提交才AC了。(注意不一定是用log2(), 采用换底公式的写法,换成log()函数)
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <math.h> #include <cmath> #include <iostream> #include <string> #include <queue> #include <stack> #include <vector> #include <algorithm> #define N 100000+100 using namespace std; int n, m; int f[N]; //poj 3264 int st_max[N][22]; int st_min[N][22]; void ST_prepare() { int i, j; for(i=1; i<=n; i++){ st_min[i][0]=f[i]; st_max[i][0]=f[i]; } for(j=1; (1<<j)<=n; j++){ for(i=1; i+(1<<j)-1<=n; i++){ st_min[i][j]=min(st_min[i][j-1], st_min[i+(1<<(j-1))][j-1] ); st_max[i][j]=max(st_max[i][j-1], st_max[i+(1<<(j-1))][j-1] ); } //一开始写只写了求最小值的,内层for循环没写括号, 导致后来添加上求最大值后,运行就是不对 } //预处理 //因为疏忽 内层循环执行两个命令却没有大括号,,,debug半天,以后切记 } int RMQ_ST_min(int li, int ri) { int k=log2(ri-li+1); return min(st_min[li][k], st_min[ri-(1<<k)+1][k] ); } int RMQ_ST_max(int li, int ri) { int k=log2(ri-li+1); return max(st_max[li][k], st_max[ri-(1<<k)+1][k] ); } int main() { int i, j; scanf("%d %d", &n, &m); for(i=1; i<=n; i++) scanf("%d", &f[i]); //建立数组 ST_prepare(); int li, ri; while(m--){ scanf("%d %d", &li, &ri); //printf("%d---%d", RMQ_ST_max(li, ri), RMQ_ST_min(li, ri) ); printf("%d\n", RMQ_ST_max(li, ri)-RMQ_ST_min(li, ri) ); } return 0; }
poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】
标签:
原文地址:http://www.cnblogs.com/yspworld/p/4690324.html