hdu 3530(單調佇列)
阿新 • • 發佈:2019-01-22
傳送門
題解:
用一個單調不升的佇列維護最大值,一個單調不減的佇列維護最小值。如果不滿足條件,後移答案區間左端點,取兩個佇列頭指標的元素較小的一個(位置儘量靠前使區間儘量長)。
#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;
}