/*
pku3264
大意是给你一串数字,然后问你从第i个到第j个中最大的数减去最小的数的值
线段树模型是这样的,先初始化一颗线段树,然后边读取数据边做预处理,
把每组读进的数据经过的路径都更新对应节点的最大值和最小值。
比如第4个数据经过的路径就是<1,6>--<3,6>--<3,4>&&<4,6>--<4,5>
OK~ 这个插入复杂度logn. N个数据总共是Nlogn ,没问题,完全可以接受。
*/
#include <iostream>
using namespace std;
#define size 400000
#define inf 2147483647
struct tree
{
int left;
int right;
int max;
int min;
};
tree xds[size];线段树数组
void init(int left,int right,int step)建树
{
int left_1=2*step;
int right_1=2*step+1;
xds[step].left=left;
xds[step].right=right;
xds[step].min=inf;
xds[step].max=0;
if(right-left<=1)return;
init(left,(left+right)/2,left_1);
init((left+right)/2,right,right_1);
}
int kk=0;
void cr(int n,int step)插入操作
{
int left=2*step;
int right=2*step+1;
if(n>xds[step].max)
xds[step].max=n;
if(n<xds[step].min)
xds[step].min=n;
if(kk>=xds[left].left&&kk<=xds[left].right)
cr(n,left);
if(kk>=xds[right].left&&kk<=xds[right].right)
cr(n,right);
return ;
}
tree search(int left,int right,int step)/查询
{
tree ret;
int left_1=2*step;
int right_1=2*step+1;
if(left==xds[step].left&&right==xds[step].right)
{
return xds[step];
}
if(left<xds[left_1].right)
{
if(right<=xds[left_1].right)
{
ret=search(left,right,left_1);
}
else///注意这儿,线段分段查询时的处理要注意
{
tree t1=search(left,xds[left_1].right,left_1);
tree t2=search(xds[right_1].left,right,right_1);
if(t1.max>t2.max)
t2.max=t1.max;
if(t1.min<t2.min)
t2.min=t1.min;
return t2;
}
}
else
{
return search(left,right,right_1);
}
return ret;
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
init(1,n,1);
int i;
int k;
int k1,k2;
for(i=1;i<=n;i++)
{
kk=i;
scanf("%d",&k);
cr(k,1);
}
for(i=0;i<m;i++)
{
scanf("%d %d",&k1,&k2);
if(k1==k2)
{
printf("0\n");
continue;
}
tree ret=search(k1,k2,1);
printf("%d\n",ret.max-ret.min);
}
}
return 0;
}