hdu 3530 单调队列最值
Posted Aragaki
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3530 单调队列最值相关的知识,希望对你有一定的参考价值。
/** HDU 3530 单调队列的应用 题意: 给定一段序列,求出最长的一段子序列使得该子序列中最大最小只差x满足m<=x<=k。 解题思路: 建立两个单调队列分别递增和递减维护(头尾删除,只有尾可插入) Max - Min 为两个队列的队首之差while(Max-Min>K) 看哪个的队首元素比较前就移动谁的 最后求长度时,需要先记录上一次的被淘汰的最值位置last ,这样[last+1,i]即为满足条件的连续子序列了 i - last */ #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> using namespace std; const int N=100005; int q_max[N],q_min[N];//递增,递减 int a[N],n,m,k; int main() { while(~scanf("%d%d%d",&n,&m,&k)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); int head_min=0,head_max=0,tail_min=0,tail_max=0; int left1=0,left2=0; int maxx=0; for(int i=1;i<=n;i++) { while(head_min<tail_min&&a[q_min[tail_min-1]]<=a[i]) tail_min--; while(head_max<tail_max&&a[q_max[tail_max-1]]>=a[i]) tail_max--; q_max[tail_max++]=q_min[tail_min++]=i; /* printf("***%d 递减、递增***\n",i); for(int j=head_min;j<tail_min;j++) printf("%d ",a[q_min[j]]); printf("\n"); for(int j=head_max;j<tail_max;j++) printf("%d ",a[q_max[j]]); printf("\n");*/ while(a[q_min[head_min]]-a[q_max[head_max]]>k) { if(q_min[head_min]<q_max[head_max]) left1=q_min[head_min++]; else left2=q_max[head_max++]; } if(a[q_min[head_min]]-a[q_max[head_max]]>=m) maxx=max(maxx,i-max(left1,left2)); } printf("%d\n",maxx); } return 0; } /* 5 2 3 1 -1 2 -6 5 5 1 3 1 2 3 4 5 6 0 0 -1 0 2 1 125 -5 */
以上是关于hdu 3530 单调队列最值的主要内容,如果未能解决你的问题,请参考以下文章