/*
线段树
*/
#include <iostream>
#include <cstdio>
using namespace std;
const int INF = 0xffffff0;
int maxV = -INF;
int minV = INF;
struct Node // 节点
{
int L, R;
int maxV, minV;
int Mid()
{
return (L + R) / 2;
}
};
struct Node tree[1000010]; //4 * n
void BuildTree(int root, int L, int R) // 建树
{
tree[root].L = L;
tree[root].R = R;
tree[root].maxV = -INF;
tree[root].minV = INF;
if(L != R)
{
BuildTree(2 * root + 1, L, (L + R) / 2);
BuildTree(2 * root + 2, (L + R) / 2 + 1, R);
}
}
void insert(int root, int i, int v)
{
if(tree[root].L == tree[root].R)
{
tree[root].maxV = tree[root].minV = v;
return;
}
tree[root].minV = min(tree[root].minV, v);
tree[root].maxV = max(tree[root].maxV, v);
if(i <= tree[root].Mid()) ///插入的时候分不清左右。。。wrong好多次
insert(2 * root + 1, i, v);
else
insert(2 * root + 2, i, v);
}
void Query(int root, int a, int b)
{
if(tree[root].maxV <= maxV && tree[root].minV >= minV)
return;
if(tree[root].L == a && tree[root].R == b)
{
minV = min(tree[root].minV, minV);
maxV = max(tree[root].maxV, maxV);
return;
}
if(b <= tree[root].Mid())
Query( 2 * root + 1, a, b);
else if (a > tree[root].Mid())
Query( 2 * root + 2, a, b);
else
{
Query( 2 * root + 1, a, tree[root].Mid());
Query( 2 * root + 2, tree[root].Mid() + 1, b);
}
}
int main ()
{
int n, q, i, v, a, b;
scanf("%d%d", &n, &q);
BuildTree(0, 1, n);
for(i = 0; i < n; ++i)
{
scanf("%d", &v);
insert(0, i + 1, v);
}
for (i = 0; i < q; ++i)
{
scanf("%d%d", &a, &b);
maxV = -INF;
minV = INF;
Query(0, a, b);
printf("%d\n", maxV - minV);
}
return 0;
}
线段树
*/
#include <iostream>
#include <cstdio>
using namespace std;
const int INF = 0xffffff0;
int maxV = -INF;
int minV = INF;
struct Node // 节点
{
int L, R;
int maxV, minV;
int Mid()
{
return (L + R) / 2;
}
};
struct Node tree[1000010]; //4 * n
void BuildTree(int root, int L, int R) // 建树
{
tree[root].L = L;
tree[root].R = R;
tree[root].maxV = -INF;
tree[root].minV = INF;
if(L != R)
{
BuildTree(2 * root + 1, L, (L + R) / 2);
BuildTree(2 * root + 2, (L + R) / 2 + 1, R);
}
}
void insert(int root, int i, int v)
{
if(tree[root].L == tree[root].R)
{
tree[root].maxV = tree[root].minV = v;
return;
}
tree[root].minV = min(tree[root].minV, v);
tree[root].maxV = max(tree[root].maxV, v);
if(i <= tree[root].Mid()) ///插入的时候分不清左右。。。wrong好多次
insert(2 * root + 1, i, v);
else
insert(2 * root + 2, i, v);
}
void Query(int root, int a, int b)
{
if(tree[root].maxV <= maxV && tree[root].minV >= minV)
return;
if(tree[root].L == a && tree[root].R == b)
{
minV = min(tree[root].minV, minV);
maxV = max(tree[root].maxV, maxV);
return;
}
if(b <= tree[root].Mid())
Query( 2 * root + 1, a, b);
else if (a > tree[root].Mid())
Query( 2 * root + 2, a, b);
else
{
Query( 2 * root + 1, a, tree[root].Mid());
Query( 2 * root + 2, tree[root].Mid() + 1, b);
}
}
int main ()
{
int n, q, i, v, a, b;
scanf("%d%d", &n, &q);
BuildTree(0, 1, n);
for(i = 0; i < n; ++i)
{
scanf("%d", &v);
insert(0, i + 1, v);
}
for (i = 0; i < q; ++i)
{
scanf("%d%d", &a, &b);
maxV = -INF;
minV = INF;
Query(0, a, b);
printf("%d\n", maxV - minV);
}
return 0;
}