背景:
集训
D
a
y
3
Day3
Day3,单调队列开启。
其实原来就会,但是好像没做几题(除了斜率优化的)。
打算用
1
1
1至
2
2
2天做一些题(太菜,大佬勿喷)。
r
a
n
k
=
20000
+
rank=20000+
rank=20000+了。
题目传送门:
https://www.luogu.org/problemnew/show/P2698
题意:
有
n
n
n个水滴,坐标为
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi),现在要你设置一个宽度竟可能小的花盆,使得它接到的所有水滴的最大时间差至少为
m
m
m(水滴每
1
s
1s
1s的路程为一个单位长度)。
思路:
还是比较显然的。
按照
x
x
x升序,用两个单调队列维护
y
y
y值得最大与最小即可。最后看看是否符合题意。
但是我们可以发现那很没必要,因为我们只需要维护最小值即可,那么,区间内符合条件的最大值一定是单调队列的最后一个。此时更新答案并弹出队首即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
int n,m,ans=(int)1e7;
int que[100010];
struct node{int x,y;} a[100010];
bool cmp(node x,node y)
{
return x.x<y.x;
}
int main()
{
int ma=0,mi=(int)1e7;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&a[i].x,&a[i].y);
ma=max(ma,a[i].y);
mi=min(mi,a[i].y);
}
sort(a+1,a+n+1,cmp);
int head=1,tail=0;
for(int i=1;i<=n;i++)
{
while(head<=tail&&a[i].y<=a[que[tail]].y) tail--;
que[++tail]=i;
while(head<=tail&&a[que[tail]].y-a[que[head]].y>=m) ans=min(ans,a[que[tail]].x-a[que[head]].x),head++;
}
printf("%d",ans==int(1e7)?-1:ans);
}