hdu 3530(单调队列)

来源:互联网 发布:mac pro2016充电器 编辑:程序博客网 时间:2024/06/03 12:57

传送门
题解:
用一个单调不升的队列维护最大值,一个单调不减的队列维护最小值。如果不满足条件,后移答案区间左端点,取两个队列头指针的元素较小的一个(位置尽量靠前使区间尽量长)。

#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;}
原创粉丝点击