Link:
Solution:
对于可行区间$[L,R]$,随着$L$的递增$R$不会递减
因此可以使用尺取法来解决此题:不断向右移动左右指针,复杂度保持线性
同时为了维护区间内的最值,要设立两个单调队列来维护最大/最小值
每次当$L$增加时,要从队列头部删去小于$L$的节点(如果后面还有不用管,以后自然会删去)
Code:
#include <bits/stdc++.h> using namespace std; typedef pair<int,int> P; #define X first #define Y second const int MAXN=1e5+10,INF=1<<30; P dat[MAXN]; int l1,l2,r1,r2,L,R; int n,d,mx[MAXN],mn[MAXN],res=INF; int main() { scanf("%d%d",&n,&d); for(int i=1;i<=n;i++) scanf("%d%d",&dat[i].X,&dat[i].Y); sort(dat+1,dat+n+1); l1=l2=1; for(L=0;L<n;L++) { while(l1<=r1&&mx[l1]<L) l1++;//尺取法 while(l2<=r2&&mn[l2]<L) l2++; while(dat[mx[l1]].Y-dat[mn[l2]].Y<d&&R<n) { R++;//维护单调栈 while(l1<=r1&&dat[mx[r1]].Y<dat[R].Y) r1--; while(l2<=r2&&dat[mn[r2]].Y>dat[R].Y) r2--; mx[++r1]=R;mn[++r2]=R; } if(dat[mx[l1]].Y-dat[mn[l2]].Y>=d) res=min(res,abs(dat[mx[l1]].X-dat[mn[l2]].X)); } printf("%d",(res==INF)?-1:res); return 0; }
Review:
对于左右边界具有单调性的区间问题可以使用滑动窗口来解决
单调性数据结构也可对此很好地维护