Description
Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值。耍畸形一个人是不行的,于是他找到了你。
0<=k<=2000,000,000
1<=n<=3000,000
1<=ai<=2000,000,000
Solution
傻傻分不清子串和子序列,看了半天题意
一个直观的想法是两个指针扫,rmq求区间最大最小值,这个十分naive的做法交上去80分
正解可以考虑开两个单调队列,这样每次比较两个队列的队头就行了
那个rec要初始化成1因为始终是从1开始的呀
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define rep(i,st,ed) for (register int i=st;i<=ed;++i)
const int N=3000005;
// int mx[N][22],mn[N][22];
int q1[N],q2[N],h1,t1=-1,h2,t2=-1;
int a[N];
int n,m,lim;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
return x*v;
}
/*
void init() {
m=read(); n=read(); lim=floor(log2(n));
rep(i,1,n) mx[i][0]=mn[i][0]=a[i]=read();
rep(i,1,lim) rep(j,1,n) {
mx[j][i]=std:: max(mx[j][i-1],mx[j+(1<<(i-1))][i-1]);
mn[j][i]=std:: min(mn[j][i-1],mn[j+(1<<(i-1))][i-1]);
}
}
int get_max(int x,int y) {
int lg=floor(log2(y-x+1));
return std:: max(mx[x][lg],mx[y-(1<<lg)+1][lg]);
}
int get_min(int x,int y) {
int lg=floor(log2(y-x+1));
return std:: min(mn[x][lg],mn[y-(1<<lg)+1][lg]);
}
void solve() {
int ans=0;
for (int i=1,j=1;j<=n;j++) {
while (i<j&&get_max(i,j)-get_min(i,j)>m) i++;
// printf("%d %d\n", i,j);
ans=std:: max(ans,j-i+1);
}
printf("%d\n", ans);
}*/
int main(void) {
// init();
// solve();
// return 0;
m=read(); n=read();
int ans=0,rec=1;
rep(i,1,n) {
int x=a[i]=read();
while (h1<=t1&&a[q1[t1]]<=x) t1--; q1[++t1]=i;
while (h2<=t2&&a[q2[t2]]>=x) t2--; q2[++t2]=i;
while (abs(a[q1[h1]]-a[q2[h2]])>m) {
if (q1[h1]<q2[h2]) rec=1+q1[h1++];
else rec=1+q2[h2++];
}
ans=std:: max(ans,i-rec+1);
}
printf("%d\n", ans);
return 0;
}