hdu3530 Subsequence (单调队列维护最值)

Posted live4m

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3530 Subsequence (单调队列维护最值)相关的知识,希望对你有一定的参考价值。

Subsequence

There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minimum element of the subsequence is no smaller than m and no larger than k.

Input

There are multiple test cases.
For each test case, the first line has three integers, n, m and k. n is the length of the sequence and is in the range [1, 100000]. m and k are in the range [0, 1000000]. The second line has n integers, which are all in the range [0, 1000000].
Proceed to the end of file.

Output

For each test case, print the length of the subsequence on a single line.

Sample Input

5 0 0
1 1 1 1 1
5 0 3
1 2 3 4 5

Sample Output

5
4

分析:

建两个单调队列,
一个维护元素i左侧最大元素下标
一个维护元素i左侧最小元素下标
当差值大于k的时候下标小的先出队,直到差值小于等于k
因为最后一次出栈的元素就是当前入栈元素能扩展到的最左位置,下标越小表示区间长度越大
然后判断是否大于等于m,如果满足更新答案

code:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
//#define ll long long
//#define int long long
#include<deque>
using namespace std;
const int maxm=1e5+6;
int n,m,k;
int a[maxm];
signed main()
    while(scanf("%d%d%d",&n,&m,&k)==3)
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        
        deque<int>q;//递增,队头存最小
        deque<int>qq;//递减,队头存最大
        int ans=0;
        int last=1;//每个元素最左扩展范围
        for(int i=1;i<=n;i++)
            while(!q.empty()&&a[i]<a[q.back()])//导致队头不为最小
                q.pop_back();
            
            q.push_back(i);
            while(!qq.empty()&&a[i]>a[qq.back()])//导致队头不为最大
                qq.pop_back();
            
            qq.push_back(i);
            while(a[qq.front()]-a[q.front()]>k)
                if(qq.front()<q.front())//坐标小的出队,这样保证last更小,向左扩展更大
                    last=qq.front()+1;
                    qq.pop_front();
                else
                    last=q.front()+1;
                    q.pop_front();
                
            
            if(a[qq.front()]-a[q.front()]>=m)
                ans=max(ans,i-last+1);
            
        
        printf("%d\\n",ans);
    
    return 0;

以上是关于hdu3530 Subsequence (单调队列维护最值)的主要内容,如果未能解决你的问题,请参考以下文章

hdu3530 Subsequence (单调队列维护最值)

HDU-3530 Subsequence(单调队列)

HDU3530 Subsequence (单调队列)

Subsequence HDU - 3530

hdu3530(单调队列)

Subsequence(hdu3530)