BZOJ——2096: [Poi2010]Pilots

http://www.lydsy.com/JudgeOnline/problem.php?id=2096

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 962  Solved: 501
[Submit][Status][Discuss]

Description

Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值。耍畸形一个人是不行的,于是他找到了你。

Input

输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度。第二行为n个由空格隔开的整数ai(1<=ai<=2000,000,000),表示难度序列。

Output

输出:最大的字串长度。

Sample Input

3 9
5 1 3 5 8 6 6 9 10

Sample Output

4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)

HINT

 

Source

单调队列维护一个最大值和最小值,因为最大值不会变小,最小值不会变大,

所以每当出现差值大于K的情况是,需要弹出最靠前的最大数或最小数

 1 #include <cstdio>
 2 
 3 #define max(a,b) ((a)>(b)?(a):(b))
 4 
 5 inline void read(int &x)
 6 {
 7     x=0; register char ch=getchar();
 8     for(; ch>'9'||ch<'0'; ) ch=getchar();
 9     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
10 }
11 const int N(3000005);
12 int qmin[N],hmin,tmin;
13 int qmax[N],hmax,tmax;
14 int n,k,a[N],pre,ans;
15 
16 int Presist()
17 {
18     read(k),read(n);
19     for(int i=1; i<=n; ++i)
20     {
21         read(a[i]);
22         for(; hmin<=tmin&&a[qmin[tmin]]>a[i]; ) tmin--;
23         qmin[++tmin]=i;
24         for(; hmax<=tmax&&a[qmax[tmax]]<a[i]; ) tmax--;
25         qmax[++tmax]=i;
26         for(; a[qmax[hmax]]-a[qmin[hmin]]>k; )
27             if(qmax[hmax]<qmin[hmin]) pre=qmax[hmax++];
28             else pre=qmin[hmin++];
29         ans=max(ans,i-pre);
30     }
31     printf("%d
",ans);
32     return 0;
33 }
34 
35 int Aptal=Presist();
36 int main(int argc,char**argv){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7701220.html