题意:
查询一个区间的最大值与最小值之差。
思路:
build构造线段树
query_mi查询区间最小值
query_ma查询区间最大值
再用最大值减去最小值得出结果。
注意:线段树要开四倍
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
int n,m,a[50005];
struct node
{
int l,r,ma,mi;
}tree[50005*4];
void push_up(int id)
{
tree[id].ma=max(tree[id*2].ma,tree[id*2+1].ma);
tree[id].mi=min(tree[id*2].mi,tree[id*2+1].mi);
}
void build(int id,int l,int r)
{
tree[id].l=l;
tree[id].r=r;
if(l==r)
{
tree[id].ma=tree[id].mi=a[l];
return;
}
int mid=l+(r-l)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
push_up(id);
}
int query_mi(int id,int l,int r)
{
int L=tree[id].l,R=tree[id].r;
if(l<=L&&R<=r)
{
return tree[id].mi;
}
if(l>R||r<L)
return 1000005;
int ans=1000005;
if(tree[id*2].r>=l)
{
ans=min(ans,query_mi(id*2,l,r));
}
if(tree[id*2+1].l<=r)
{
ans=min(ans,query_mi(id*2+1,l,r));
}
return ans;
}
int query_ma(int id,int l,int r)
{
int L=tree[id].l,R=tree[id].r;
if(l<=L&&R<=r)
{
return tree[id].ma;
}
if(l>R||r<L)
return 0;
int ans=0;
if(tree[id*2].r>=l)
{
ans=max(ans,query_ma(id*2,l,r));
}
if(tree[id*2+1].l<=r)
{
ans=max(ans,query_ma(id*2+1,l,r));
}
return ans;
}
int main()
{
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
while(m--)
{
scanf("%d%d",&x,&y);
printf("%d\n",query_ma(1,x,y)-query_mi(1,x,y));
}
return 0;
}