zoukankan      html  css  js  c++  java
  • [POI2010]PIL-Pilots

    洛咕

    题意:给定一个长度为(n(n<=1e6))的序列,求最长的最大值与最小值相差不超过(k)的序列的长度.

    分析:维护两个单调队列,一个维护最大值,一个维护最小值,转移之前判断如果最大值减最小值超过(k),哪边的队头下标小就清除哪边的队头,同时记录一下踢出的队头的最大值(last),那么此时([last+1,i])就是一段合法的区间.这里就能解释为什么哪边的队头下标小就清除哪边的队头了,因为我们要保证长度最长,所以(last)越小越好.

    (O_2)玄学(RE???)没救了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=1e6+5;
    int k,n,a[N],q1[N],q2[N];
    int main(){
    	k=read();n=read();for(int i=1;i<=n;++i)a[i]=read();
    	int l1=1,r1=0,l2=1,r2=0,ans=0,last=0;
    	for(int i=1;i<=n;++i){
    		while(l1<=r1&&a[i]>a[q1[r1]])--r1;q1[++r1]=i;
    		while(l2<=r2&&a[i]<a[q2[r2]])--r2;q2[++r2]=i;
    		while(a[q1[l1]]-a[q2[l2]]>k){
    			if(q1[l1]<q2[l2])last=max(last,q1[l1]),++l1;
    			else if(q1[l1]>q2[l2])last=max(last,q2[l2]),++l2;
    		}
    		ans=max(ans,i-last);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    初始mysql语句
    MySQL 数据库 的安装和基本管理
    POJ 3685
    总结-LCT
    $亲属关系$
    一:包装好和吹出去 二:三国心得
    创业心得
    阿里前CEO卫哲的万字长文:被马云骂醒,看透B2B 10大核心问题!
    英雄不问出处, 看看商界大佬年轻时受过的苦
    最应该富养的,不是孩子是妻子!
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11815760.html
Copyright © 2011-2022 走看看