题目大意:给一列数,给一些询问,问[a,b]内最大值-最小值是多少
分析:比较简单的题目。以点建树,建树时,遇到叶子节点则读入,max = min = 读入值,否则用左右儿子的最大最小值来更新当前节点的最大最小值。查询就不多说了
很裸的线段树,一次ac
#include <iostream>
#include<stdio.h>
#include<cmath>
using namespace std;
const int MAX=50010;
int h[MAX],ma,mi;
typedef struct
{
int left,right;
int MAX,MIN;
}pe;
pe p[4*MAX];
void build(int k,int left,int right)
{
p[k].left=left;
p[k].right=right;
if(left==right)
{
p[k].MAX=h[left];
p[k].MIN=h[left];
return;
}
int mid=(left+right)>>1,c1=k<<1,c2=c1+1;
build(c1,left,mid);
build(c2,mid+1,right);
p[k].MAX=max(p[c1].MAX,p[c2].MAX);
p[k].MIN=min(p[c1].MIN,p[c2].MIN);
}
void query(int k,int a,int b)
{
if(p[k].left>b||p[k].right<a)
return;
int m1=p[k].MAX,m2=p[k].MIN;
if(p[k].left>=a&&b>=p[k].right)
{
ma=max(m1,ma);
mi=min(m2,mi);
//cout<<k<<" "<<ma<<" "<<mi<<endl;
return;
}
int mid=(p[k].left+p[k].right)>>1,c1=k<<1,c2=c1+1;
{
if(mid>=b)
query(c1,a,b);
else
if(mid<a)
query(c2,a,b);
else
if(mid>=a&&b>mid)
{
query(c1,a,mid);
query(c2,mid+1,b);
}
}
}
int main()
{
int N,Q,a,b;
scanf("%d%d",&N,&Q);
for(int i=1;i<=N;i++)
scanf("%d",&h[i]);
build(1,1,N);
for(int i=0;i<Q;i++)
{
scanf("%d%d",&a,&b);
ma=0;
mi=1000010;
query(1,a,b);
printf("%d\n",ma-mi);
}
return 0;
}