题意
求一个子序列满足 最大值 - 最小值 <= k的最大长度。
解析
假设之前最大的是a[4],最小的是a[5]
连续子串已经是 a[0] ~ a[10]
这时候判断a[11]是否符合,
两种情况
一种a[11]比a[4]大
这时候判断他 a[11] - min <= k 是否符合
假如不符合
就向前查找,第一个a[j] >= (a[11] - k)的数字
这时候子串长度 = 11 - j 的位置
变成了min = a[j], max = a[11]
不要被数据范围给吓到了,n虽然有10万,但是最小值和最大是满足单调递增的,所以不会算很慢。
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int a[N], n, k;
int main() {
while(scanf("%d%d", &n, &k) != EOF) {
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
int maxa, mina;
maxa = mina = a[0];
int ans, len;
ans = len = 1;
for(int i = 1; i < n; i++) {
if(a[i] > maxa) {
maxa = a[i];
if(a[i] - mina <= k) {
len++;
}else {
int j;
mina = INF;
for(j = i; j >= 0; j--) {
if(abs(a[i] - a[j]) > k) break;
mina = min(mina, a[j]);
}
len = i - j;
}
}else if(a[i] < mina) {
mina = a[i];
if(maxa - a[i] <= k) {
len++;
}else {
int j;
maxa = -INF;
for(j = i; j >= 0; j--) {
if(abs(a[j] - a[i]) > k) break;
maxa = max(maxa, a[j]);
}
len = i - j;
}
}else {
len++;
}
ans = max(ans, len);
}
printf("%d\n", ans);
}
return 0;
}