题目描述
题解
由于满足r是随着l单调的,那么两个指针扫一遍即可。
扫的过程中要判断扩展的r是否合法,可以用单调队列维护处l~r这一段的最大值和最小值,然后随便判断一下。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 3000005
int k,n,l,r,lmax,rmax,lmin,rmin,ans;
int a[N],qmax[N],qmin[N];
struct hp{int Max,Min;};
void push(int id)
{
while (lmax<rmax&&a[qmax[rmax]]<=a[id]) --rmax;
qmax[++rmax]=id;
while (lmin<rmin&&a[qmin[rmin]]>=a[id]) --rmin;
qmin[++rmin]=id;
}
hp pop(int id)
{
while (lmax<rmax&&qmax[lmax+1]<id) ++lmax;
int Max=a[qmax[lmax+1]];
while (lmin<rmin&&qmin[lmin+1]<id) ++lmin;
int Min=a[qmin[lmin+1]];
return (hp){Max,Min};
}
int main()
{
scanf("%d%d",&k,&n);
for (int i=1;i<=n;++i) scanf("%d",&a[i]);
l=r=1;lmax=rmax=lmin=rmin=0;push(l);
while (l<=n)
{
if (l>r)
{
r=l;lmax=rmax=lmin=rmin=0;push(l);
}
while (r<n)
{
hp now=pop(l);
if (a[r+1]>now.Max)
{if (a[r+1]-now.Min>k) break;}
else if (a[r+1]<now.Min)
{if (now.Max-a[r+1]>k) break;}
++r;push(r);
}
ans=max(ans,r-l+1);
++l;
}
printf("%d\n",ans);
}