求区间内最大数和最小数的差,用两棵线段树,一个维护区间最大值,一个维护区间最小值。
#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>
#include <time.h>
using namespace std;
#define QUADMEMSET
inline void QuadMemSet(void* dst, int iSize, int value)
{
iSize = iSize / 4;
int* newDst = (int*) dst;
#ifdef WIN32
__asm
{
mov edi, dst
mov ecx, iSize
mov eax, value
rep stosd
}
#else
for (int i = 0; i < iSize;i++)
{
newDst[i] = value;
}
#endif
}
#define MAXN 132000
int ST[2][MAXN];
#define MAXVALUE 1000000
#define MINVALUE 0
template<class TYPE>
void UpdateValue(TYPE st[],int i, TYPE value, int N, bool bMin)
{
i += N - 1;
st[i] = value;
while (i > 0)
{
i = (i - 1) / 2;
if (bMin)
{
st[i] = min(st[i * 2 + 1], st[i * 2 + 2]);
}
else
st[i] = max(st[i * 2 + 1], st[i * 2 + 2]);
}
}
template<class TYPE>
TYPE QueryST(TYPE st[], int a, int b, int l, int r, int k, bool bMin)
{
if (l > b || a > r)
{
return bMin ? MAXVALUE : MINVALUE;
}
if (l >= a && b >= r)
{
return st[k];
}
else
{
TYPE value1 = QueryST(st, a, b, l, (r + l) / 2, k * 2 + 1, bMin);
TYPE value2 = QueryST(st, a, b, (r + l) / 2 + 1, r, k * 2 + 2, bMin);
if (bMin)
{
return min(value1, value2);
}
else
{
return max(value1, value2);
}
}
}
int main()
{
#ifdef _DEBUG
freopen("e:\\in.txt", "r", stdin);
#endif
QuadMemSet(ST[0], sizeof(ST[0]), MAXVALUE);
QuadMemSet(ST[1], sizeof(ST[1]), MINVALUE);
int N, Q;
scanf("%d %d", &N, &Q);
int maxn = 1;
while (maxn < N)
{
maxn *= 2;
}
for (int i = 0; i < N; i++)
{
int value;
scanf("%d", &value);
UpdateValue<int>(ST[0], i, value, maxn, true);
UpdateValue<int>(ST[1], i, value, maxn, false);
}
for (int i = 0; i < Q;i++)
{
int a, b;
scanf("%d %d", &a, &b);
int maxr = QueryST<int>(ST[1], a - 1, b - 1, 0, maxn - 1, 0, false);
int minr = QueryST<int>(ST[0], a - 1, b - 1, 0, maxn - 1, 0, true);
printf("%d\n", maxr - minr);
}
return 0;
}