状态转移方程:d[i, j]=max(d[i, j-1],d[i+2^(j-1), j-1])
#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define M 100001
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
int n,rmin[M][16],rmax[M][16],a[M];
void rmqinit()
{
int i,j;
for(i=1; i<=n; ++i) rmin[i][0] = rmax[i][0] = a[i];
int r = floor(log(n)/log(2.0));
for(i=1; i<=r; ++i)
for(j=n; j>=1; --j)
{
if(j + (1<<i) - 1 <= n)
{
rmin[j][i] = min(rmin[j][i-1], rmin[j+(1<<(i-1))][i-1]);
rmax[j][i] = max(rmax[j][i-1], rmax[j+(1<<(i-1))][i-1]);
}
}
}
int retmin(int x, int y)
{
int r = floor(log(double(y-x+1))/log(2.0));
return min(rmin[x][r], rmin[y-(1<<r)+1][r]);
}
int retmax(int x, int y)
{
int r = floor(log(double(y-x+1))/log(2.0));
return max(rmax[x][r], rmax[y-(1<<r)+1][r]);
}
int main()
{
int m,i,j,pes,x,y;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1; i<=n; ++i)
scanf("%d",&a[i]);
rmqinit();
for(i=0; i<m; ++i)
{
scanf("%d%d",&x,&y);
printf("%d\n",retmax(x,y)-retmin(x,y));
}
}
return 0;
}