题目意思是:给你一组数,在给你一个范围,要你求这个范围里最大值与最小值的差。
思路:用线段树做,节点保存线段的左右端点,最大值和最小值。
/*
* File: main.cpp
* Author: Administrator
*
* Created on 2010年1月23日, 下午4:02
*/
#include <stdlib.h>
#include <iostream>
using namespace std;
#define N 50005
struct node {
int l, r;
int _max, _min;
} Tree[N * 3];
int a[N];
int Max(int a, int b) {
if (a >= b)return a;
else return b;
}
int Min(int a, int b) {
if (a <= b)return a;
else return b;
}
void Build_Tree(int l, int r, int k) {
Tree[k].l = l;
Tree[k].r = r;
if (l == r) {
Tree[k]._max = a[l];
Tree[k]._min = a[l];
return;
}
int mid = (l + r) / 2;
Build_Tree(l, mid, 2 * k);
Build_Tree(mid + 1, r, 2 * k + 1);
Tree[k]._max = Max(Tree[2 * k]._max, Tree[2 * k + 1]._max);
Tree[k]._min = Min(Tree[2 * k]._min, Tree[2 * k + 1]._min);
}
int Find_max(int l, int r, int k) {
if (Tree[k].l == l && Tree[k].r == r) {
return Tree[k]._max;
}
int mid = (Tree[k].l + Tree[k].r) / 2;
if (r <= mid)return Find_max(l, r, 2 * k);
else if (l > mid)return Find_max(l, r, 2 * k + 1);
else {
int a, b;
a = Find_max(l, mid, 2 * k);
b = Find_max(mid + 1, r, 2 * k + 1);
return Max(a, b);
}
}
int Find_min(int l, int r, int k) {
if (Tree[k].l == l && Tree[k].r == r) {
return Tree[k]._min;
}
int mid = (Tree[k].l + Tree[k].r) / 2;
if (r <= mid)return Find_min(l, r, 2 * k);
else if (l > mid)return Find_min(l, r, 2 * k + 1);
else {
int a, b;
a = Find_min(l, mid, 2 * k);
b = Find_min(mid + 1, r, 2 * k + 1);
return Min(a, b);
}
}
/*
*
*/
int main(int argc, char** argv) {
int n, q, i, j;
while (scanf("%d%d", &n, &q) != EOF) {
for (i = 1; i <= n; i++) {
//cin>>a[i];
scanf("%d", &a[i]);
}
Build_Tree(1, n, 1);
while (q--) {
scanf("%d%d", &i, &j);//system("pause");
int ma = Find_max(i, j, 1);
int mb = Find_min(i, j, 1);
cout << ma - mb << endl;
}
}
return (EXIT_SUCCESS);
}