线段树水题,每个结点保存两个信息,当前区间的最大、最小值,但是容易TLE。
下面是代码:
#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxn 50500
#define INF 100000000
int h[maxn];
int min_h,max_h;
struct Node
{
int l;
int r;
int Min;
int Max;
} node[maxn*5];
void push_up(int rt)
{
node[rt].Max = max(node[rt<<1].Max,node[rt<<1|1].Max);
node[rt].Min = min(node[rt<<1].Min,node[rt<<1|1].Min);
}
void build(int l,int r,int rt)
{
node[rt].l = l;
node[rt].r = r;
node[rt].Max = node[rt].Min = 0;
if(l == r)
{
node[rt].Min = node[rt].Max = h[l];
return ;
}
int mid = (l + r) >> 1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
push_up(rt);
}
void query(int l,int r,int rt)
{
if(min_h <= node[rt].Min && max_h >= node[rt].Max) return ;
if(node[rt].l == node[rt].r)
{
min_h = min(min_h,node[rt].Min);
max_h = max(max_h,node[rt].Max);
return ;
}
int mid = (node[rt].l+ node[rt].r) >> 1;
if(r <= mid) query(l,r,rt<<1);
else if(l > mid) query(l,r,rt<<1|1);
else
{
query(l,mid,rt<<1);
query(mid+1,r,rt<<1|1);
}
return ;
}
int main()
{
int N,Q;
scanf("%d%d",&N,&Q);
for(int i = 1; i <= N; i++) scanf("%d",&h[i]);
build(1,N,1);
for(int i = 1; i <= Q; i++)
{
int l,r;
min_h = INF;
max_h = -INF;
scanf("%d%d",&l,&r);
query(l,r,1);
printf("%d\n",max_h-min_h);
}
return 0;
}