思路:线段树求区间最大最小值
#include <iostream>
#include <stdio.h>
#include <cstring>
#define MAXN 300000
using namespace std;
typedef long long ll;
ll a[MAXN];
struct note
{
int rr,ll;
long long mm,nn;
}q[MAXN*3];
void build(int i,int l,int r)
{
q[i].rr=r;
q[i].ll=l;
if(l==r)
{
q[i].mm=q[i].nn=a[l];
return ;
}
int m=(l+r)/2;
build(i*2,l,m);
build(i*2+1,m+1,r);
q[i].mm=max(q[i*2].mm,q[i*2+1].mm);
q[i].nn=min(q[i*2].nn,q[i*2+1].nn);
}
ll query1(int i,int l,int r)
{
if(l<=q[i].ll&&r>=q[i].rr)
{
return q[i].mm;
}
int m=(q[i].ll+q[i].rr)/2;
if(r<=m)
return query1(i*2,l,r);
else if(l>m)
return query1(i*2+1,l,r);
else
return max(query1(i*2,l,r),query1(i*2+1,l,r));
}
ll query2(int i,int l,int r)
{
if(l<=q[i].ll&&r>=q[i].rr)
{
return q[i].nn;
}
int m=(q[i].ll+q[i].rr)/2;
if(r<=m)
return query2(i*2,l,r);
else if(l>m)
return query2(i*2+1,l,r);
else
return min(query2(i*2,l,r),query2(i*2+1,l,r));
}
int main()
{
// freopen("in.txt","r",stdin);
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
int x,y;
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
printf("%lld\n",query1(1,x,y)-query2(1,x,y));
}
}
}