传送门
题解:
用一个单调不升的队列维护最大值,一个单调不减的队列维护最小值。如果不满足条件,后移答案区间左端点,取两个队列头指针的元素较小的一个(位置尽量靠前使区间尽量长)。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e5+4;
int n,m,k;
int q1[MAXN],q2[MAXN],a[MAXN];
int st1,ed1,st2,ed2;
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
int main() {
// freopen("hdu 3530.in","r",stdin);
while (~scanf("%d%d%d",&n,&m,&k)) {
int ans=0,pos=0;
for (register int i=1;i<=n;++i) a[i]=read();
st1=st2=ed1=ed2=0;
for (register int i=1;i<=n;++i) {
while (st1<ed1&&a[q1[ed1-1]]<a[i]) --ed1;
while (st2<ed2&&a[q2[ed2-1]]>a[i]) --ed2;
q1[ed1++]=q2[ed2++]=i;
while (st1<ed1&&st2<ed2&&a[q1[st1]]-a[q2[st2]]>k) {
if (q1[st1]<q2[st2]) pos=q1[st1++];
else pos=q2[st2++];
}
if (st1<ed1&&st2<ed2&&a[q1[st1]]-a[q2[st2]]>=m) ans=max(ans,i-pos);
}
printf("%d\n",ans);
}
return 0;
}
本文介绍了一种使用单调队列实现的滑动窗口算法,该算法可以高效地找到数组中满足特定条件的最大子数组长度。通过维护两个单调队列分别记录窗口内的最大值和最小值,确保了算法的时间复杂度为O(n)。
&spm=1001.2101.3001.5002&articleId=78230763&d=1&t=3&u=d44d4d13929645ccad150975daf6bfb1)
1万+

被折叠的 条评论
为什么被折叠?



