分析:
线性结构问题,可以用线段树解决
每个结点维护:
mx:区间最大值
mn:区间最小值
ls:从左向右走得到的最大差值
rs:从右向左走得到的最大差值
对于ls和rs的维护:
ans.ls=max(lc.ls,rc.ls,rc.mx−lc.mn)
a
n
s
.
l
s
=
m
a
x
(
l
c
.
l
s
,
r
c
.
l
s
,
r
c
.
m
x
−
l
c
.
m
n
)
ans.rs=max(lc.rs,rc.rs,lc.mx−rc.mn)
a
n
s
.
r
s
=
m
a
x
(
l
c
.
r
s
,
r
c
.
r
s
,
l
c
.
m
x
−
r
c
.
m
n
)
线段树区间询问即可
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=1e9;
const int N=200005;
struct node{
int x,y,mx,mn,ls,rs;
};
node t[N<<2],ans;
int n,m,a[N];
node update(node lc,node rc)
{
node ans;
ans.x=lc.x; ans.y=rc.y;
ans.mx=max(lc.mx,rc.mx);
ans.mn=min(lc.mn,rc.mn);
ans.ls=max(max(lc.ls,rc.ls),rc.mx-lc.mn);
ans.rs=max(max(lc.rs,rc.rs),lc.mx-rc.mn);
return ans;
}
void build(int bh,int l,int r)
{
t[bh].x=l; t[bh].y=r;
if (l==r)
{
t[bh].mx=t[bh].mn=a[l];
return;
}
int mid=(l+r)>>1;
build(bh<<1,l,mid);
build(bh<<1|1,mid+1,r);
t[bh]=update(t[bh<<1],t[bh<<1|1]);
}
void ask(int bh,int l,int r,int x,int y)
{
if (l>=x&&r<=y)
{
ans=update(ans,t[bh]);
return;
}
int mid=(l+r)>>1;
if (x<=mid) ask(bh<<1,l,mid,x,y);
if (y>mid) ask(bh<<1|1,mid+1,r,x,y);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
int x,y,opt=0;
scanf("%d%d",&x,&y);
if (x==y) {
printf("0\n");
continue;
}
if (x>y) opt=1,swap(x,y);
ans.mn=INF; ans.mx=-INF; ans.rs=ans.ls=0;
ask(1,1,n,x,y);
if (opt) printf("%d\n",ans.rs);
else printf("%d\n",ans.ls);
}
return 0;
}