hdu3530 Subsequence 单调队列

//    hdu3530 Subsequence 单调队列
//    题目大意:找到一个最大的子串,使得子串区间内最大值和最小值的差
//    在low和up范围内,串的规模10w。

//    解题思路:

//    单调队列,单调队列可以保留i位置之前的最大值和最小值的下标,有了这些
//    则,每次我们比较两个队列的队头,看差值是否大于up,(因为它是到i位置最大
//    的差值,其他值不可能比i还要大.)

//    如果大于,则将两个对头靠前的那个丢掉,即出队,再比较对头,并且记录下
//    出队的位置下标,(因为此时出队的与到i的串的左边界有关),之后就是在
//    到i为止的最大值最小值之差如果大于等于low,这时i-上面记录的出队的较大
//    的位置就是到i的串的最大的长度。

//    感悟:

//    这道题想到了用两个单调队列分别保留最大值和最小值,但是出队的顺序,我并没有
//    很清楚,只知道一定会出队的,我之前的考虑是对两个对头比较,这是毫无疑问的,
//    之后对那个进行++操作呢,如果一起加,肯定是有问题,所以不是很清楚。之后看了看
//    各位大神的结题报告,发现,哪个在前面就出去就可以了,最后出队的取个最大的就是
//    左边界-1的值。
//    行百里者半九十,恰恰是最后的十让人撕心裂肺,欲罢不能,继续加油

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 1e5 + 1000;

int n,low,up;
int a[MAX_N];
int deqmi[MAX_N];
int deqmx[MAX_N];

void input(){
    for (int i = 1;i <= n; i++){
        cin >> a[i];
    }
}

void solve(){
    int head1 = 0,tail1 = 0;
    int head2 = 0,tail2 = 0;
    int mx = 0;
    int last1=0,last2=0;
    for (int i=1;i<=n;i++){

        while(head1 < tail1 && a[deqmi[tail1-1]] >= a[i])
            tail1--;
        deqmi[tail1++] = i;
        while(head2 < tail2 && a[deqmx[tail2-1]] <= a[i])
            tail2--;
        deqmx[tail2++] = i;

        while(a[deqmx[head2]] - a[deqmi[head1]]>up){
        //    while(head1 < tail1 && a[deqmx[head1]] - a[deqmi[head2] >= )
            if (deqmx[head2]>deqmi[head1]){
                last1 = deqmi[head1++];
            }else {
                last2 = deqmx[head2++];
            }
        }

        if (a[deqmx[head2]] - a[deqmi[head1]] >= low){
            mx = max(mx,i-max(last1,last2));
        }
    }

    cout << mx << endl;

}

int main(){
    ios::sync_with_stdio(false);
    while(cin >> n >> low >> up){
        input();
        solve();
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 13:37:56

hdu3530 Subsequence 单调队列的相关文章

hdu3530 双单调队列的维护

单调队列有部分堆的功能,但其只能维护给定区间中比v大的值或者比v小的值,且其一般存储元素的下标. 思路:两个单调队列维护最大值与最小值的下标,如果区间的最大值最小值之差大于给定范围,则选择队首靠左的删去,并记录删去元素的下标,然后维护最大区间长度即可 注意有两个范围,第二个范围不能忽略 /* 单调队列存储区间最大值,最小值 如果Max-Min>k,呢么左端点靠前的删掉队头元素,删掉时记录下标 */ #include<iostream> #include<cstring> #i

单调队列总结

单调队列 就是保持队列中的元素始终保持单调性,这个数据结构就是单调队列 它的作用就是维护最值.求第一个比i小(大)的数的下标等等 还有个单调栈来着,不过我们可以用一个双端队列就足够了 如果要维护最大值,就用单调递减队列,反之,用递增队列 1.hdu3530 Subsequence 单调队列入门题 这题求的是最大值减去最小值不小于m不大于k的最长长度 这题用单调队列维护最大值和最小值即可 #include<iostream> using namespace std; #define MAX 10

单调队列————[USACO09MAR]向右看齐Look Up

先了解一下单调队列: 很明显的具有单调性 分为单调递增和单调递减两种,简单点讲就是维护队头为最大值或者为最小值 (建议采用双向队列  比较好写) 具体步骤:(这个是单调递减) 如果队列非空且当前值比队尾元素大,不断删除比该值小的元素,否则直接队尾入队 while(!que.empty()&&ma[i]>que.back()) {     que.pop_back(); } que.push_back(i); 单调队列的作用:: 1):可以用来维护区间的单调性,用来解决最大或最小的问题

[hdu3530]单调队列

题意:求满足最大元素与最小元素之差在一定范围的连续区间的最大长度.单调队列经典应用. 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstdlib> 5 #include <cstring> 6 #include <map> 7 #include <queue> 8 #include <deque> 9

hdu 3415 单调队列

Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5690    Accepted Submission(s): 2059 Problem Description Given a circle sequence A[1],A[2],A[3]......A[n]. Circle s

hdu 3530 (单调队列)

Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4441    Accepted Submission(s): 1457 Problem Description There is a sequence of integers. Your task is to find the longest subsequenc

POJ 3017 单调队列dp

Cut the Sequence Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8764   Accepted: 2576 Description Given an integer sequence { an } of length N, you are to cut the sequence into several parts every one of which is a consecutive subseque

Max Sum of Max-K-sub-sequence(单调队列)

Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7034    Accepted Submission(s): 2589 Problem Description Given a circle sequence A[1],A[2],A[3]......A[n]. Circle se

HDU 3530 单调队列

Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3995    Accepted Submission(s): 1308 Problem Description There is a sequence of integers. Your task is to find the longest subsequenc