这次算的是区间内,两值只差最大是多少,那就分别存入最大,最小值,两者之差不就是答案了。
//区间之内,[a,b]间两数之差最大的
//存最大最小值
//一个是先算最小,在算最大,跑两边
//一个是最大最小一起跑
//然而时间复杂度差不多
#include<iostream>
#include<cstdio>
#include<cstring>
#define oo 1000010
const int maxn = 50050;
using namespace std;
struct node
{
int mx,mi;
};
int Max(int x, int y)
{
return x > y ? x : y;
}
int Min(int x, int y)
{
return x < y ? x : y;
}
node tree[maxn<<2];
void work(int rt)
{
tree[rt].mi = Min(tree[rt<<1].mi, tree[rt<<1|1].mi);
tree[rt].mx = Max(tree[rt<<1].mx, tree[rt<<1|1].mx);
}
void build(int l, int r, int rt)
{
if(l == r)
{
int a;
scanf("%d",&a);
tree[rt].mi = tree[rt].mx = a;
return;
}
int mid = (l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
work(rt);
}
int querymin(int x, int y,int l, int r, int rt)
{
if(x<=l&&r<=y)
return tree[rt].mi;
int mid = (l+r)>>1, ans = oo;
if(x<=mid)
ans = Min(ans, querymin(x,y,l,mid,rt<<1));
if(mid<y)
ans = Min(ans, querymin(x,y,mid+1,r,rt<<1|1));
return ans;
}
int querymax(int x, int y,int l, int r, int rt)
{
if(x<=l&&r<=y)
return tree[rt].mx;
int mid = (l+r)>>1, ans = -oo;
if(x<=mid)
ans = Max(ans, querymax(x,y,l,mid,rt<<1));
if(mid<y)
ans = Max(ans, querymax(x,y,mid+1,r,rt<<1|1));
return ans;
}
void query(int x, int y,int l, int r, int rt,int &mp, int &mq)
{
if(x<=l&&r<=y)
{
mp = tree[rt].mi;
mq = tree[rt].mx;
return;
}
int mid = (l+r)>>1, ans1 = oo,ans2 = -oo,p,q;
if(x<=mid)
{
query(x,y,l,mid,rt<<1,p,q);
ans1 = Min(ans1, p);
ans2 = max(ans2, q);
}
if(mid<y)
{
query(x,y,mid+1,r,rt<<1|1,p,q);
ans1 = Min(ans1, p);
ans2 = max(ans2, q);
}
mp = ans1;
mq = ans2;
}
int main()
{
int n,q,a,b;
while(scanf("%d%d",&n,&q)!=EOF)
{
build(1,n,1);
while(q--)
{
scanf("%d%d",&a,&b);
//
//printf("%d\n",querymax(a,b,1,n,1)-querymin(a,b,1,n,1));
int dd,xx;
query(a,b,1,n,1,xx,dd);
printf("%d\n",dd-xx);
}
}
return 0;
}