基础的线段树
/*
PROG:
LANG: C++11
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <deque>
#include <set>
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <time.h>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef pair<int, int> P;
const ll MOD = 1000000007;
const int INF = 0x7fffffff;
const int MAXN = 50001;
struct node {
int left, right, ma, mi;
} tree[MAXN*4];
int num[MAXN];
void build(int i, int l, int r){
tree[i].left = l;
tree[i].right = r;
if(l == r){
tree[i].ma = num[l];
tree[i].mi = num[l];
return ;
}
int mid = (l+r)/2;
build(2*i, l, mid);
build(2*i+1, mid+1, r);
tree[i].mi = min( tree[i*2+1].mi, tree[2*i].mi);
tree[i].ma = max( tree[i*2+1].ma, tree[2*i].ma);
}
// first is ma, second is mi
P query(int i, int l, int r){
P ans;
if(tree[i].left == l && tree[i].right == r){
ans.first = tree[i].ma;
ans.second = tree[i].mi;
return ans;
}
int mid = (tree[i].left + tree[i].right)/2;
if( r <= mid)
ans = query(i*2, l, r);
else if( l > mid)
ans = query(i*2+1, l, r);
else{
P p1 = query(i*2, l, mid);
P p2 = query(i*2+1, mid+1, r);
ans.first = max(p1.first, p2.first);
ans.second = min(p1.second, p2.second);
}
return ans;
}
int main()
{
int N, Q;
scanf("%d%d", &N, &Q);
for(int i = 1; i <= N; i++){
scanf("%d", &num[i]);
}
build(1,1,N);
int a, b;
for(int i = 0; i < Q; i++){
scanf("%d%d", &a, &b);
P pp = query(1,a,b);
printf("%d\n", pp.first - pp.second);
}
return 0;
}