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
5 1 3 5 8 6 6 9 10
Sample Output
4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是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){;}