題目大意:
給定整數 n 和 x,以及一個大小爲 n 的序列 a。
你可以選擇一個區間 [l,r],然後令 a[i]+=d(l<=i<=r),其中 d 滿足 |d|<=x。
要求最大化 a 的最長上升子序列的長度,並輸出該值
n<=200000,x<=10^9
分析:
代碼:
#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)
#define N 200005
using namespace std;
struct Node {
int id, num, rmax;
}C[N];
int f1[N], f2[N], dp[N], a[N], n, m, top, ans;
void read(int &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s >= '0' && s <= '9') { x = x * 10 + (s - '0'); s = getchar(); }
x = x * f;
}
int main() {
freopen("glo.in", "r", stdin);
freopen("glo.out", "w", stdout);
read(n); read(m);
rep(i, 1, n) read(a[i]);
f1[1] = 1; dp[++top] = a[1];
rep(i, 2, n) {
if (a[i] > dp[top]) {
dp[++top] = a[i];
f1[i] = top;
}
else
if (a[i] + m > dp[top]) {
f1[i] = top + 1;
int id = lower_bound(dp + 1, dp + top + 1, a[i]) - dp;
dp[id] = a[i];
} else {
f1[i] = lower_bound(dp + 1, dp + top + 1, a[i] + m) - dp;
int id = lower_bound(dp + 1, dp + top + 1, a[i]) - dp;
dp[id] = a[i];
}
}
f2[n] = 1; dp[top = 1] = -a[n];
rwp(i, n - 1, 1) {
if (-a[i] > dp[top]) {
dp[++top] = -a[i];
f2[i] = top;
}
else {
int id = lower_bound(dp + 1, dp + top + 1, -a[i]) - dp;
f2[i] = id;
dp[id] = -a[i];
}
}
rep(i, 1, n) ans = max(ans, f1[i] + f2[i] - 1);
printf("%d\n", ans);
return 0;
}