用两个单调队列维护序列中的最大值和最小值即可。
poi~
#include<cstdio> #include<algorithm> using namespace std; int m,n,head[2]={1,1},tail[2]={1,1},q[2][3000001],a[3000001],ans; int main() { scanf("%d%d",&m,&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); q[0][1]=q[1][1]=1; int i=2,j=1; while(1) { while(i<=n&&a[q[1][head[1]]]-a[q[0][head[0]]]<=m) { while(a[i]<=a[q[0][tail[0]]] && tail[0]>=head[0]) --tail[0]; q[0][++tail[0]]=i; while(a[i]>=a[q[1][tail[1]]] && tail[1]>=head[1]) --tail[1]; q[1][++tail[1]]=i; ++i; } if(i>n) { if(a[q[1][head[1]]]-a[q[0][head[0]]]<=m) ans=max(ans,i-j); else ans=max(ans,i-j-1); break; } ans=max(ans,i-j-1); for(j=min(q[0][head[0]],q[1][head[1]]); a[q[1][head[1]]]-a[q[0][head[0]]]>m; ++j) { if(q[0][head[0]]==j) ++head[0]; if(q[1][head[1]]==j) ++head[1]; } } printf("%d ",ans); return 0; }