Subsequence(两个单调队列) Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5716    Accepted Submission(s): 1884

Problem Description
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
 

题解:

一个序列的最大值与最小值的差在m和k之间;

单调队列。

维护最大值和最小值,如果发现最大值和最小值的差大于k,那么就移动下标最靠前的队列。

注意如下数据:

5 2 4

2 1 5 2 2

应该用一个last标记上一个移动的位置,然后答案就是max{i-last},之前没有这个标记wa了一次。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
const int MAXN = 1000010;
int num[MAXN];
int q1[MAXN], q2[MAXN];
int main(){
    int n, m, k;
    while(~scanf("%d%d%d", &n, &m, &k)){
        for(int i = 0; i < n; i++)
            scanf("%d", num + i);
        int h1 = 0, t1 = -1, h2 = 0, t2 = -1;
        int ans = 0;
        int last = -1;
        for(int i = 0; i < n; i++){
            while(h1 <= t1 && num[q1[t1]] > num[i])
                t1--;
            while(h2 <= t2 && num[q2[t2]] < num[i])
                t2--;
            q1[++t1] = i;
            q2[++t2] = i;
            while(h1 <= t1 && h2 <= t2 && num[q2[h2]] - num[q1[h1]] > k){
                if(q1[h1] < q2[h2])
                    last = q1[h1++];
                else
                    last = q2[h2++];
            }
            if(h1 <= t1 && h2 <= t2 && num[q2[h2]] - num[q1[h1]] >= m){
                ans = max(ans, i - last);
            }
        }
        printf("%d
", ans);
    }
    return 0;
}