洛谷传送门
BZOJ传送门
题目大意
给定 n , k n,k n,k和一个长度为 n n n的序列,求最长的最大值最小值相差不超过 k k k的序列
输入输出格式
输入格式:
第一行两个有空格隔开的整数 k k k( 0 ≤ k ≤ 2000 , 000 , 000 0\le k\le 2000,000,000 0≤k≤2000,000,000), n ( 1 ≤ n ≤ 3000 , 000 ) n(1\le n\le 3000,000) n(1≤n≤3000,000), k k k代表设定的最大值, n n n代表序列的长度。第二行为 n n n个由空格隔开的整数 a i a_i ai( 1 ≤ a i ≤ 2000 , 000 , 000 1\le a_i\le 2000,000,000 1≤ai≤2000,000,000),表示序列。
输出格式:
Your program should print a single integer to the standard output:
the maximum length of a fragment of the flight that is within the given tolerance level.
一个整数代表最大的符合条件的序列
输入输出样例
输入样例#1:
3 9
5 1 3 5 8 6 6 9 10
输出样例#1:
4
说明
样例解释: 5 , 8 , 6 , 6 5, 8, 6, 6 5,8,6,6 和 8 , 6 , 6 , 9 8, 6, 6, 9 8,6,6,9都是满足条件长度为 4 4 4的序列
解题分析
两个单调队列, 一个维护最小值, 一个维护最大值, 即可 A C \mathcal{AC} AC本题。
代码如下:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <cmath>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 3000500
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
for (; !isdigit(c); c = gc);
for (; isdigit(c); c = gc)
x = (x << 1) + (x << 3) + c - 48;
}
template <class T> IN T max(T a, T b) {return a > b ? a : b;}
int dat[MX], mn[MX], mx[MX];
int l, r, lmin, rmin, lmax, rmax, len, lim, ans;
int main(void)
{
in(lim), in(len);
for (R int i = 1; i <= len; ++i) in(dat[i]);
l = lmin = lmax = 1;
for (R int i = 1; i <= len; ++i)
{
++r;
W (lmin <= rmin && dat[mn[rmin]] > dat[r]) --rmin;
W (lmax <= rmax && dat[mx[rmax]] < dat[r]) --rmax;
mn[++rmin] = mx[++rmax] = r;
W (dat[mx[lmax]] - dat[mn[lmin]] > lim)
{
++l;
if (mn[lmin] < l) ++lmin;
if (mx[lmax] < l) ++lmax;
}
ans = max(ans, r - l + 1);
}
printf("%d", ans);
}