zoukankan      html  css  js  c++  java
  • hdu 3530 单调队列最值

    /**
    HDU 3530  单调队列的应用
    题意:
         给定一段序列,求出最长的一段子序列使得该子序列中最大最小只差x满足m<=x<=k。
    解题思路:
         建立两个单调队列分别递增和递减维护(头尾删除,只有尾可插入)
         Max - Min 为两个队列的队首之差while(Max-Min>K) 看哪个的队首元素比较前就移动谁的
         最后求长度时,需要先记录上一次的被淘汰的最值位置last ,这样[last+1,i]即为满足条件的连续子序列了
    i - last
    */
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int N=100005;
    int q_max[N],q_min[N];//递增,递减
    int a[N],n,m,k;
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            int head_min=0,head_max=0,tail_min=0,tail_max=0;
            int left1=0,left2=0;
            int maxx=0;
            for(int i=1;i<=n;i++)
            {
                while(head_min<tail_min&&a[q_min[tail_min-1]]<=a[i])
                    tail_min--;
                while(head_max<tail_max&&a[q_max[tail_max-1]]>=a[i])
                    tail_max--;
                q_max[tail_max++]=q_min[tail_min++]=i;
               /* printf("***%d 递减、递增***
    ",i);
                for(int j=head_min;j<tail_min;j++)
                       printf("%d ",a[q_min[j]]);
                printf("
    ");
                for(int j=head_max;j<tail_max;j++)
                       printf("%d ",a[q_max[j]]);
                printf("
    ");*/
                while(a[q_min[head_min]]-a[q_max[head_max]]>k)
                {
                    if(q_min[head_min]<q_max[head_max])
                          left1=q_min[head_min++];
                    else
                          left2=q_max[head_max++];
                }
                if(a[q_min[head_min]]-a[q_max[head_max]]>=m)
                      maxx=max(maxx,i-max(left1,left2));
            }
            printf("%d
    ",maxx);
        }
        return 0;
    }
    /*
    5 2 3
    1 -1 2 -6 5
    5 1 3
    1 2 3 4 5
    6 0 0
    -1 0 2 1 125 -5
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+5;
    int a[maxn], q1[maxn], q2[maxn];
    int main()
    {
        int n, m, k;
        while(cin>>n>>m>>k) {
            for(int i = 0; i<n; i++) {
                scanf("%d", &a[i]);
            }
            int st1 = 0, st2 = 0, ed1 = 0, ed2 = 0, ans = 0, now = 0;
            for(int i = 0; i<n; i++) {
                while(st1<ed1&&a[q1[ed1-1]]<a[i])       //q1维护一个单调递减的数列,这样队头元素是最大值, 第二个是第二大的值
                    ed1--;
                while(st2<ed2&&a[q2[ed2-1]]>a[i])       //q2维护一个单调递增的数列, 队头是最小值。
                    ed2--;
                q1[ed1++] = q2[ed2++] = i;              
                while(st1<ed1&&st2<ed2&&a[q1[st1]]-a[q2[st2]]>k) {      //如果最大值-最小值大于k
                    if(q1[st1]<q2[st2]) {
                        now = q1[st1++]+1;                 //如果最大值在序列中的位置小于最小值
                    } else {
                        now = q2[st2++]+1;
                    }
                }
                if(st1<ed1&&st2<ed2&&a[q1[st1]]-a[q2[st2]]>=m) {
                    ans = max(ans, i-now+1);                //只有最大值-最小值大于等于m的时候才更新ans
                }
            }
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    Java 泛型 泛型的约束与局限性
    Java 泛型 泛型方法
    Java 泛型 泛型数组
    Java 泛型 协变性、逆变性
    Java 泛型 协变式覆盖和泛型重载
    Java 泛型 泛型代码和虚拟机
    Insertion Sort List
    Remove Duplicates from Sorted List II
    String to Integer (atoi)
    SpringMvc源码入门
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7647121.html
Copyright © 2011-2022 走看看