[P2698][USACO12MAR]花盆Flowerpot

Link:

P2698 传送门

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:

对于左右边界具有单调性的区间问题可以使用滑动窗口来解决

单调性数据结构也可对此很好地维护

原文地址:https://www.cnblogs.com/newera/p/9337954.html