Description
Input
Output
Sample Input
4
3
2
4
3
3
1 1 3 2
3 3 4 2
1 3 3 4
Sample Output
3
2
5
Data Constraint
思路
大致路径是先横再往上/下再横着走,如果到之间的 最小值(线段树维护区间最小值) 比和都小,那么需要额外从y1走到m 并从m 走到 y2;其他情况都是 |x1-x2|+|y1-y2|
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e5+77,inf=0x3f3f3f3f;
int tr[maxn*3],a[maxn],n,t,tmp,ans,q;
int abs(int x)
{
return x<0?-x:x;
}
void build(int l,int r,int u)
{
if(l==r)
{
tr[u]=a[l]; return;
}
int mid=(l+r)>>1;
build(l,mid,u*2); build(mid+1,r,u*2+1);
tr[u]=min(tr[u*2],tr[u*2+1]);
}
int query(int l,int r,int st,int ed,int u)
{
if (l<=st&&ed<=r) return tr[u];
int mid=(st+ed)/2,res=inf;
if (l<=mid) res=min(res,query(l,r,st,mid,u*2));
if (mid<r) res=min(res,query(l,r,mid+1,ed,u*2+1));
return res;
}
int main()
{
freopen("cusor.in","r",stdin); freopen("cusor.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
build(1,n,1);
scanf("%d",&q);
while (q--)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
t=abs(y1-y2)+abs(x1-x2);
if (abs(x1-x2)<=1) ans=t;
else if (x1<x2)
{
tmp=query(x1+1,x2-1,1,n,1);
if(y1>tmp&&y2>tmp) ans=y1-tmp+y2-tmp+x2-x1;
else ans=t;
} else
{
tmp=query(x2+1,x1-1,1,n,1);
if(y1>tmp&&y2>tmp) ans=y1-tmp+y2-tmp+x1-x2;
else ans=t;
}
printf("%d\n",ans);
}
}