1. 程式人生 > >hdu 3530(單調佇列)

hdu 3530(單調佇列)

傳送門
題解:
用一個單調不升的佇列維護最大值,一個單調不減的佇列維護最小值。如果不滿足條件,後移答案區間左端點,取兩個佇列頭指標的元素較小的一個(位置儘量靠前使區間儘量長)。

#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; }