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

题意:

让我们找到一个最长子序列,使得这个子序列中的最大值和最小值相差不超过k不小于m

分析:

可以用一个单调队列来维护序列的最大值和最小值,如果最大值与最小值之差大于k,那么就让最大值队列的队首或最小值队列的队首中位置较小的那个出队,直到满足最大值与最小值之差小于等于k,选位置较小的出队是因为要使序列的长度最长,出队后的新区间的起点为出队的位置+1.因为只要除去那个最小值之后成立,说明次小值满足了条件,那么从出队位置+1起之后的部分到i点一定满足,然后再判断最大值与最小值之差是否满足大于等于m,这样区间的长度就是i-L(其中L是最后一个不满足条件的位置,相当于i-第一个满足条件的位置+1,一样的),我们发现这样的区间必须是连续的,因为题目只要求了最大最小只差满足一定条件,所以只要区间包含这样的最大最小值,包含他们的连续区间必然是更长的,所以我们选择连续的区间。

如果小于m不必出队,因为出队不可能使它们的差变大,如果大于等于m再考虑更新ans。

code:

#include 
using namespace std;
const int maxn = 1e5+10;
int n,m,k,num[maxn],qmin[maxn],qmax[maxn],dp;
int lmin,rmin,lmax,rmax;
int main(){
    while(~scanf("%d%d%d",&n,&m,&k)){
        lmax = lmin = 0;
        rmax = rmin = -1;
        dp = 0;
        int l = 0;
        for(int i = 1; i <= n; i++){
            scanf("%d",&num[i]);
            while(lmin <= rmin && num[qmin[rmin]] > num[i]) rmin--; //递增
            qmin[++rmin] = i;
            while(lmax <= rmax && num[qmax[rmax]] < num[i]) rmax--; //递减
            qmax[++rmax] = i;
            while(num[qmax[lmax]] - num[qmin[lmin]] > k)//如果当前最大值和最小值差值大于k
                l = (qmax[lmax] < qmin[lmin]) ? qmax[lmax++] : qmin[lmin++];//仍然选择较小左端点优先
            if(num[qmax[lmax]] - num[qmin[lmin]] >= m){
                dp = max(dp,i-l);
            }
        }
        printf("%d\n",dp);
    }
    return 0;
}

你可能感兴趣的:(单调栈单调队列)