/**//* 题意:给出一个序列,求最长的连续子序列,使得 M<=Max-Min<=K n <= 10^5 一开始我把Max-Min合起来弄,搞不出 然后看了别人说用两个单调队列,一个存单调递减,一个存单调递增 想了下细节,1y,有点惊奇..
我知道单调队列可以快速知道i及之前的最大/小值,这道题分开两个队列来做很好!!
Max - Min 为两个队列的队首之差 while(Max-Min>K) 看哪个的队首元素比较前就移动谁的
最后求长度时,需要先记录上一次的被淘汰的最值位置last ,这样[last+1,i]即为满足条件的连续子序列了 i - last */ #include<cstdio> #include<cstring> #include<algorithm>
using namespace std;
inline int min(int a ,int b){return a<b?a:b;} inline int max(int a ,int b){return a>b?a:b;}
const int MAXN = 100010;
int a[MAXN]; int DQ1[MAXN],DQ2[MAXN];//Max, Min
int main() { //freopen("in","r",stdin); int N,M,K; while(~scanf("%d%d%d",&N,&M,&K)) { for(int i=1;i<=N;i++) scanf("%d",&a[i]); int ans = 0; int front1 = 0,tail1 = 0; int front2 = 0,tail2 = 0; int last1 = 0,last2 = 0; for(int i=1;i<=N;i++) { //Max while(front1<tail1 && a[DQ1[tail1-1]]<=a[i])tail1--; DQ1[tail1++] = i; //Min while(front2<tail2 && a[DQ2[tail2-1]]>=a[i])tail2--; DQ2[tail2++] = i;
while(a[DQ1[front1]]-a[DQ2[front2]] > K) { if(DQ1[front1]<DQ2[front2])last1 = DQ1[front1++]; else last2 = DQ2[front2++]; } if(a[DQ1[front1]]-a[DQ2[front2]]>=M) ans = max(ans,i-max(last1,last2));//取较大值 } printf("%d\n",ans); } return 0; }
|
|
常用链接
随笔分类
Links
搜索
最新评论
|
|