Description
Solution
树状数组存一下最长不下降子序列
两个序列乱搞一下
离散化很麻烦
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define lowbit(x) (x & (-x))
#define MAXN 400010
ll n, X, Ans, l, cnt;
ll tA[MAXN], tB[MAXN], A[MAXN], B[MAXN];
struct rec {
int val, e, a, x;
} t[MAXN];
inline ll read() {
ll s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
inline bool cmp1(rec x, rec y) {
return x.val < y.val;
}
inline bool cmp2(rec x, rec y) {
return x.e < y.e;
}
void addA(ll x, ll y) { for (; x <= 400010; x += lowbit(x)) tA[x] = max(tA[x], y); }
ll queryA(ll x) { ll ans = 0; for (; x; x -= lowbit(x)) ans = max(ans, tA[x]); return ans; }
void addB(ll x, ll y) { for (; x <= 400010; x += lowbit(x)) tB[x] = max(tB[x], y); }
ll queryB(ll x) { ll ans = 0; for (; x; x -= lowbit(x)) ans = max(ans, tB[x]); return ans; }
inline ll Work() {
ll ans = 0;
for (register ll i = 1; i <= n; i++) {
A[i] = queryA(t[i].a - 1) + 1;
B[i] = max(queryA(t[i].a - 1 + t[i].x) + 1, queryB(t[i].a - 1) + 1);
addA(t[i].a, A[i]);
addB(t[i].a, B[i]);
ans = max(max(ans, A[i]), B[i]);
}
return ans;
}
int main() {
n = read(), X = read();
for (register ll i = 1; i <= n; i++)
t[i].val = read(), t[i].e = i;
sort(t + 1, t + n + 1, cmp1);
for (register int i = 1; i <= n; i++)
if (t[i - 1].val == t[i].val)
t[i].a = cnt;
else
t[i].a = ++cnt;
l = 1;
t[n + 1].val = 2147483647;
for (register int i = 1; i <= n; i++) {
while (t[i].val + X >= t[l].val)
l++;
l--;
t[i].x = t[l].a - t[i].a + 1;
if (t[l].val == t[i].val + X) t[i].x--;
}
sort(t + 1, t + n + 1, cmp2);
printf("%lld", Work());
return 0;
}