「题解」洛谷 P3512 [POI2010]PIL-Pilots
题目
简化题意
问你一段序列中最长的最大值与最小值的差不超过一定值的子序列的长度
思路
单调队列。
分别维护最大值和最小值以及下标。
当最大值与最小值的差不在限制内就弹出队首。
在限制内就就更新答案(需要用到上次弹出的数的下标)。
Code
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 3000001
int max(int a, int b) { return a > b ? a : b; }
int n, k, ans, last;
struct Node {
int w, id;
};
struct deque {
Node a[MAXN];
int head, tail;
Node front() { return a[head]; }
Node back() { return a[tail]; }
void add(int x, int id) { a[++tail].w = x, a[tail].id = id; }
void del_back() { --tail; }
void del_front() { ++head; }
bool empty() { return tail < head; }
}q1, q2;
int main() {
scanf("%d %d", &k, &n);
q1.tail = q2.tail = 0, q1.head = q2.head = 1;
for (int i = 1, x; i <= n; ++i) {
scanf("%d", &x);
while (!q1.empty() && x >= q1.back().w) {
q1.del_back();
}
q1.add(x, i);
while (!q2.empty() && x <= q2.back().w) {
q2.del_back();
}
q2.add(x, i);
Node a = q1.front(), b = q2.front();
while (a.w - b.w > k) {
if (a.id < b.id) {
q1.del_front();
last = a.id;
}
else {
q2.del_front();
last = b.id;
}
a = q1.front();
b = q2.front();
}
ans = max(i - last, ans);
}
printf("%d\n", ans);
return 0;
}