BZOJ 2096: [Poi2010]Pilots

Description

求一个最长的序列,最大值最小值之差不超过 \(k\) .

Sol

单调队列.

一个队列直接上就行..

Code

/**************************************************************
    Problem: 2096
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:4024 ms
    Memory:71604 kb
****************************************************************/

#include <bits/stdc++.h>
using namespace std;

#define debug(a) cout<<#a<<"="<<a<<" "

typedef long long LL;
const int N = 3e6+50;

LL n,k,ans;
LL a[N];
LL q[2][N],h[2],t[2],l;

inline LL in(LL x=0,char ch=getchar()) { while(ch>‘9‘ || ch<‘0‘) ch=getchar();
    while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();return x; }
int main() {
    k=in(),n=in();
    for(int i=1;i<=n;i++) a[i]=in();

    ans=1;
    q[0][h[0]=t[0]=1]=1,q[1][h[1]=t[1]=1]=1,l=1;

    for(int i=2;i<=n;i++) {
        while(h[0]<=t[0] && a[i]<a[q[0][t[0]]]) t[0]--;
        q[0][++t[0]]=i;

//      cout<<i<<":"<<endl;
//      for(int j=h[0];j<=t[0];j++) cout<<q[0][j]<<endl;

        while(h[1]<=t[1] && a[i]>a[q[1][t[1]]]) t[1]--;
        q[1][++t[1]]=i;

//      for(int j=h[1];j<=t[1];j++) cout<<q[1][j]<<endl;

        for(;a[q[1][h[1]]]-a[q[0][h[0]]]>k;l++) {
            if(q[0][h[0]]==l) h[0]++;
            if(q[1][h[1]]==l) h[1]++;
        }
        ans=max(ans,i-l+1);
//      debug(l),debug(ans)<<endl;
//      cout<<"--------------------"<<endl;
    }cout<<ans<<endl;
    return 0;
}
时间: 2024-10-13 10:58:19

BZOJ 2096: [Poi2010]Pilots的相关文章

单调队列 BZOJ 2096 [Poi2010]Pilots

2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 819  Solved: 418[Submit][Status][Discuss] Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0

BZOJ 2096 Poi2010 Pilots 单调队列

题目大意:给定一个序列,求一个最长的子串,使最大值与最小值之差不超过k 从左到右枚举右端点,利用单调队列维护当前区间中的最大值和最小值 如果某一时刻当前区间的最大值和最小值之差超过了k,就向右调整左端点直到差小于等于k为止 时间复杂度O(n) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 3003003 using namespa

2096: [Poi2010]Pilots单调队列题解

Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度.第二行为n个由空格隔开的整数ai(1<=ai<=2000,000,000),表

bzoj2096[Poi2010]Pilots 单调队列

2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 983  Solved: 513[Submit][Status][Discuss] Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0

bzoj2096[Poi2010]Pilots*

bzoj2096[Poi2010]Pilots 题意: 给一个序列和一个最大值,要求找一个最长连续子串,使里面任意两个数相差不超过这个最大值.序列大小≤3000000 题解: 用两个单调队列,分别维护当前区间的最大值和最小值,然后用双指针法. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5

【BZOJ2096】[Poi2010]Pilots 双指针+单调队列

[BZOJ2096][Poi2010]Pilots Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度.第二行为n个由空格隔开的整数ai(1&

BZOJ 2086: [Poi2010]Blocks

2086: [Poi2010]Blocks Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 494  Solved: 222[Submit][Status][Discuss] Description 给出N个正整数a[1..N],再给出一个正整数k,现在可以进行如下操作:每次选择一个大于k的正整数a[i],将a[i]减去1,选择a[i-1]或a[i+1]中的一个加上1.经过一定次数的操作后,问最大能够选出多长的一个连续子序列,使得这个子序列的每个数

BZOJ 2080: [Poi2010]Railway 双栈排序

2080: [Poi2010]Railway Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 140  Solved: 35[Submit][Status][Discuss] Description 一个铁路包含两个侧线1和2,右边由A进入,左边由B出去(看下面的图片) 有n个车厢在通道A上,编号为1到n,它们被安排按照要求的顺序(a1,a2,a3,a4....an)进入侧线,进去还要出来,它们要按照编号顺序(1,2,3,4,5....n)从通道B

bzoj 2084: [Poi2010]Antisymmetry -- manacher

2084: [Poi2010]Antisymmetry Time Limit: 10 Sec  Memory Limit: 259 MB Description 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串.比如00001111和010101就是反对称的,1001就不是.现在给出一个长度为N的01字符串,求它有多少个子串是反对称的. Input 第一行一个正整数N (N <= 500,000).第二行一个长度为N的01字符串. Output