zoukankan      html  css  js  c++  java
  • HDU3530 Subsequence (单调队列)

    维护两个单调队列一个递增一个递减

    如果两个差值大于l,那么把位置小的往后移,因为这样才能保证合法,不然比如最大值在1处,最小值在2处,现在我们移动最小值是不可能的,因为最小值始终在最大值和右端点的中间,无法移动,只能移动最大值,那么注意的是,如果移动后合法,那么当前的有效区间跟移动后在哪无关,其实是原先的地方+1,下面我们来举个例子

    假如最大值在1处 最小值在3处且不满足条件,那么就找次大值,变成新的最大值假如在4处,那么有效区间是从2开始的,与3和4无关。

    本题在做第三个比大小关系的时候无需判断队列是否为空,因为当前数永远存在,所以队列不可能为空。

    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    const int inf=0x3f3f3f3f;
    int q1[N];
    int q2[N];
    int a[N];
    int main(){
        int i;
        int n,m,k;
        while(cin>>n>>m>>k){
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            int hh1=0;
            int tt1=-1;
            int hh2=0;
            int tt2=-1;
            int pos=0;
            int ans=0;
            for(i=1;i<=n;i++){
                while(hh1<=tt1&&a[q1[tt1]]<=a[i])
                    tt1--;
                q1[++tt1]=i;
                while(hh2<=tt2&&a[q2[tt2]]>=a[i])
                    tt2--;
                q2[++tt2]=i;
                while(a[q1[hh1]]-a[q2[hh2]]>k){
                    if(q1[hh1]<q2[hh2]){
                        pos=q1[hh1++];
                    }
                    else{
                        pos=q2[hh2++];
                    }
                }
                if(a[q1[hh1]]-a[q2[hh2]]>=m){
                    ans=max(ans,i-pos);
                }
            }
            cout<<ans<<endl;
        }
    }
    View Code
  • 相关阅读:
    对我最重要的三个老师
    究竟 javascript 错误处理有哪些类型?
    前端小白凭什么杀进 BAT?
    金九银十,换工作热潮来临!
    适用于Java开发人员的SOLID设计原则简介
    在5分钟内将Spring Boot作为Windows服务启动
    Redis中的Java分布式缓存
    Arrays工具类详解
    SpringBoot整合redis
    java 数组用法详解
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12494335.html
Copyright © 2011-2022 走看看