发现当端点值差最小时本区间一定不可以更新,所以最终答案一定是一段端点价值差最小的区间
本题类似分治的做法,可以先将子区间的答案算出来,然后对于穿过mid的部分,我们只需要找到差比ans小的,记录下来,可更新的答案一定在这些点之间,然后枚举更新即可。
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
int n,a[N];
struct node{
int x,y;
}q[N],tmp[N];
int val(node a,node b){
return max(abs(b.y-a.y)+1,abs(a.x-b.x));
}
bool cmp(node a,node b){
return a.x<b.x;
}
int get(int l,int r){
if(l==r) return N*5;
if(r==l+1) return max(2,abs(q[l].x-q[r].x));
int mid=((l+r)>>1);
int mn=N*5;
mn=min(mn,get(l,mid));
mn=min(mn,get(mid+1,r));
int cnt=0;
for(int i=l;i<=mid;i++){
if(abs(q[mid].y-q[i].y)<mn)tmp[++cnt].x=q[i].x,tmp[cnt].y=q[i].y;
}
for(int i=mid+1;i<=r;i++){
if(abs(q[i].y-q[mid+1].y)<mn)tmp[++cnt].x=q[i].x,tmp[cnt].y=q[i].y;
else break;
}
sort(tmp+1,tmp+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
for(int j=i+1;j<=cnt&&(abs(tmp[j].x-tmp[i].x)<=mn);j++){
mn=min(mn,val(tmp[i],tmp[j]));
}
return mn;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
q[i].x=a[i],q[i].y=i;
}
printf("%d",get(1,n));
}