Description
Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值。耍畸形一个人是不行的,于是他找到了你。
Input
输入:
第一行两个有空格隔开的整数
k(0≤k≤2000000000),n(1≤n≤3000000)
,
k
代表Tz设定的最大值,
第二行为
n
个由空格隔开的整数
Output
输出:最大的字串长度。
Sample Input
3 9
5 1 3 5 8 6 6 9 10
Sample Output
4
(有两个子串的长度为
4
:
solution
任意两个难度差不会超过他设定的最大值其实只需要最大值减去最小值不超过他设定的最大值就好了,正确性显然..
所以我们维护两个单调队列,一个单调递增,一个单调递减
那两个队列的队首就分别是最大值和最小值
如果最大值减最小值比
k 大,为了比较长,所以我们取队首元素位置靠前的然后为了方便比较,这里单调队列里存的是下标,当然也可以开一个结构体来做
还有这个东西堆也可以实现..
code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; template<typename T> void input(T &x) { x=0; T a=1; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') a=-1; for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0'; x*=a; return; } #define MAXN 3000010 int a[MAXN]; int q1[MAXN],q2[MAXN]; int head1=1,tail1=0; int head2=1,tail2=0; int main() { int n,k; input(k),input(n); for(int i=1;i<=n;i++) input(a[i]); int ans=1,Max=1; for(int i=1;i<=n;i++) { while(head1<=tail1&&a[i]<=a[q1[tail1]]) tail1--; q1[++tail1]=i; while(head2<=tail2&&a[i]>=a[q2[tail2]]) tail2--; q2[++tail2]=i; while(a[q2[head2]]-a[q1[head1]]>k) if(q2[head2]<q1[head1]) Max=q2[head2++]+1; else Max=q1[head1++]+1; ans=max(ans,i-Max+1); } printf("%d",ans); return 0; }