//题目大意:第一行给出N,Q两个数,(1<=N<=50000;1<=Q<=200000)接下来n行每一行有一个数,
//再接下来有Q组查询,每行查询给出一个区间[l,r](1<=l<=r<=N),输出该区间内最大值和最小值的差值。
//输入
//6 3
//1
//7
//3
//4
//2
//5
//1 5
//4 6
//2 2
//输出
//6
//3
//0
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=50005;
int n,q;
struct node{
int maxn,minn;
node(){//初始化赋值
maxn=0;
minn=0;
}
}tree[N<<2];//线段树一般都是4N大小,博客有很多大佬证明
void build(int k,int l,int r)//建树,k当前结点,l左边界,r右边界
{
if(l==r)
{
int a;
scanf("%d",&a);//a为给定的初值
tree[k].maxn=a;
tree[k].minn=a;
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);//向左建树
build(k<<1|1,mid+1,r);//向右建树
tree[k].maxn=max(tree[k<<1].maxn,tree[k<<1|1].maxn);//更新最大最小值
tree[k].minn=min(tree[k<<1].minn,tree[k<<1|1].minn);
}
int ma=0;//当前区间的最大值
int mi=INF;//当前区间的最小值
void query(int L,int R,int l,int r,int k)
{
if(L<=l&&r<=R)
{
if(tree[k].maxn>ma)
ma=tree[k].maxn;
if(tree[k].minn<mi)
mi=tree[k].minn;
return ;
}
int mid=(l+r)>>1;
if(L<=mid)
query(L,R,l,mid,k<<1);
if(R>mid)
query(L,R,mid+1,r,k<<1|1);
}
int main()
{
scanf("%d%d",&n,&q);
build(1,1,n);
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
ma=0;
mi=INF;
query(l,r,1,n,1);//查询[l,r]区间,更新最大最小值
printf("%d\n",ma-mi);
}
return 0;
}
如有错误,欢迎指出!