简单线段树 根节点存储最值;
不要存储差值 如果存储差值 在返回结果的时候有很多的麻烦,
所以在建树的过程中更新每个更节点的 最值,
最后直接比较区间的最值,
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 50005;
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a, b) ((a+b)>>1)
struct node
{
int lft, rht, hei, low, value;
int mid()
{
return MID(lft, rht);
}
};
int n, m, a[maxn];
int _max, _min;
struct Segtree
{
node tree[maxn*4];
void build(int lft, int rht, int inf)
{
tree[inf].lft = lft;
tree[inf].rht = rht;
if(lft == rht) tree[inf].hei = tree[inf].low = a[lft];
else
{
int mid = tree[inf].mid();
build(lft, mid, LL(inf));
build(mid+1, rht, RR(inf));
tree[inf].hei = max(tree[LL(inf)].hei, tree[RR(inf)].hei);
tree[inf].low = min(tree[LL(inf)].low, tree[RR(inf)].low);
}
}
void query(int st, int en, int inf)
{
if(st <= tree[inf].lft && tree[inf].rht <= en)
{
_max = max(_max, tree[inf].hei);
_min = min(_min, tree[inf].low);
return ;
}
int mid = tree[inf].mid();
if(st <= mid) query(st, en, LL(inf));
if(mid < en) query(st, en, RR(inf));
}
} seg;
int main()
{
while(scanf("%d %d", &n, &m) != EOF)
{
for(int i = 1; i <= n; i++) scanf("%d", a+i);
seg.build(1, n, 1);
for(int i = 1; i <= m; i++)
{
_max = -1;
_min = 99999999;
int u, v;
scanf("%d%d", &u, &v);
seg.query(u, v, 1);
printf("%d\n", _max-_min);
}
}
}
poj3264
最新推荐文章于 2020-07-05 18:38:53 发布