题目链接:http://poj.org/problem?id=3264
保存区间内的最大值与最小值 然后做差
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 200001; // 区间范围
struct
{
int l, r, m,n; // l左断电 ,r右端点 ,m为该区间的最大分数,n为该区间的最大分数
} nod[MAXN*4];
int a[MAXN];
void creat(int t, int l, int r)
{
nod[t].l = l, nod[t].r = r;
if(l == r) // 叶子节点
{
nod[t].m = a[l];
nod[t].n = a[l];
return; //递归出口
}
int m = (l+r) / 2;
creat(t*2, l, m), creat(t*2+1, m+1, r); // 左孩子
nod[t].m = max(nod[t*2].m, nod[t*2+1].m); // 右孩子
nod[t].n = min(nod[t<<1].n,nod[t<<1|1].n);
}
int query1(int t, int l, int r) // 查询t节点 在[l,r]区间范围的最大值
{
if(l == nod[t].l && r == nod[t].r)
return nod[t].m;
int s;
if(r <= nod[t*2].r)
s = query1(t*2, l, r);
else if(l >= nod[t*2+1].l)
s= query1(t*2+1, l, r);
else
s = max(query1(t*2, l, nod[t*2].r), query1(t*2+1, nod[t*2+1].l, r));
return s;
}
int query2(int t, int l, int r) // 查询t节点 在[l,r]区间范围的最小值
{
if(l == nod[t].l && r == nod[t].r)
return nod[t].n;
int s;
if(r <= nod[t*2].r)
s = query2(t*2, l, r);
else if(l >= nod[t*2+1].l)
s= query2(t*2+1, l, r);
else
s = min(query2(t*2, l, nod[t*2].r), query2(t*2+1, nod[t*2+1].l, r));
return s;
}
int main()
{
int n, m, i, x1, x2;
while(scanf("%d%d", &n, &m) != EOF)
{
for(i = 1; i <= n; i++) scanf("%d", &a[i]);
creat(1, 1, n); // 根节点标号为1,区间为[1,n]
while(m--)
{
scanf("%d%d",&x1,&x2);
printf("%d\n",query1(1,x1,x2)-query2(1,x1,x2));
}
}
return 0;
}