题意就是让你求区间最大和最小值的差值。
这题可以用线段树,也可以用Tarjan 的Sparse Table算法(参考刘汝佳训练指南197),这里我用了ST算法,还有要说明的是题目描述的数据范围是不准确的如果你数组开比50000大一点点的话是会RE的。
代码:
//poj 3263 RMQ
//2013-07-30-21.39
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int dmax[maxn][30];
int dmin[maxn][30];
int a[maxn];
void init(int n)
{
for (int i = 1; i <= n; i++)
{
dmax[i][0] = a[i];
dmin[i][0] = a[i];
}
for (int j = 1; (1<<j) <= n; j++)
{
for (int i = 1; i + j - 1 <= n; i++)
{
dmax[i][j] = max(dmax[i][j-1], dmax[i+(1<<(j-1))][j-1]);
dmin[i][j] = min(dmin[i][j-1], dmin[i+(1<<(j-1))][j-1]);
}
}
}
int RMQ(int l, int r)
{
int k = 0;
while ((1<<(k+1)) <= r-l+1) k++;
return (max(dmax[l][k], dmax[r-(1<<k)+1][k]) - min(dmin[l][k], dmin[r-(1<<k)+1][k]));
}
int main()
{
int n, q;
int l, r;
while (scanf("%d %d", &n, &q) != EOF)
{
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
init(n);
while (q--)
{
scanf("%d %d", &l, &r);
printf("%d\n", RMQ(l, r));
}
}
return 0;
}