Hdu 3530 Subsequence 单调队列

来源:互联网 发布:web portal认证软件 编辑:程序博客网 时间:2024/05/22 01:48

 题意:求出一个序列里最大元素与最小元素之差s满足条件:m<=s<=k,求出满足条件的最长的子序列的长度

思路:还是利用单调队列,设两个队列q1和q2,分别存上升序列和下降序列,上升序列的最左端最小,下降序列的最左端最大,若两者之和>k,那么调整开始序列的位置

代码:

#include <iostream>#include <stdio.h>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <map>#include <queue>#define lson l,mid,num<<1#define rson mid+1,r,num<<1|1using namespace std;const int M=100005;int q1[M];int q2[M];int a[M];int main(){    int n,m,k;    while(scanf("%d%d%d",&n,&m,&k)!=EOF)    {        int front1=0,tail1=-1,front2=0,tail2=-1;        for(int i=0;i<n;i++)        {            scanf("%d",&a[i]);        }        int mmax=0;        int start=0;        for(int i=0;i<n;i++)        {            while(front1<=tail1 && a[q1[tail1]]>=a[i])            --tail1;            q1[++tail1]=i;            while(front2<=tail2 && a[q2[tail2]]<=a[i])            --tail2;            q2[++tail2]=i;            while(a[q2[front2]]-a[q1[front1]] > k)            {                if( q1[front1] < q2[front2] )                {                    start=q1[front1]+1;                    ++front1;                }                else                {                    start=q2[front2]+1;                    ++front2;                }            }            if(a[q2[front2]]-a[q1[front1]] >= m)            {                mmax=max(mmax,i-start+1);            }        }        printf("%d\n",mmax);    }   return 0;}