[USACO 2012 MAR SILVER] Flowerpot
题面
题解
滑动窗口 双指针
窗口保持极差 (ge D) ,需要支持出队、入队、求极差
用两个单调队列维护最大最小值。
(这种单调性相反的队列中的元素是不交的(除队尾),不清楚这个性质有什么用处)
//https://www.luogu.com.cn/problem/P2698
//2021 10 20 AliCCC
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=1034567890;
const int MAXN=100111;
int N, D;
struct Pos{
int x, y;
} P[MAXN];
bool cmpx(const Pos &A, const Pos &B){
return A.x<B.x;
}
int Mx[MAXN], Mxh, Mxt;
int Mn[MAXN], Mnh, Mnt;
int main(){
scanf("%d%d", &N, &D);
for(int i=1;i<=N;++i){
scanf("%d%d", &P[i].x, &P[i].y);
}
sort(P+1, P+N+1, cmpx);
int Ans=INF;
//int Ans=N+1;
for(int i=1, j=1;i<=N;++i){
while(j<=N && P[Mx[Mxh]].y-P[Mn[Mnh]].y<D){
while(Mxh<Mxt && P[Mx[Mxt-1]].y<=P[j].y) --Mxt;
Mx[Mxt++]=j;
while(Mnh<Mnt && P[Mn[Mnt-1]].y>=P[j].y) --Mnt;
Mn[Mnt++]=j;
++j;
}
if(P[Mx[Mxh]].y-P[Mn[Mnh]].y>=D) Ans=min(Ans, abs(P[j-1].x-P[i].x)); //Ans=min(Ans, j-i);
if(Mx[Mxh]==i) ++Mxh;
if(Mn[Mnh]==i) ++Mnh;
}
printf("%d
", (Ans>=INF)?-1:Ans);
return 0;
}