为了能到远方,脚下的每一步都不能少.|

lucky_cloud

园龄:1年4个月粉丝:1关注:3

2024-02-03 22:19阅读: 22评论: 0推荐: 0

AT_abc339_e

传送门。

题意

给你一个长度为 \(N\) 的序列 \(A = (A_1, A_2, \ldots, A_N)\)

求长度为 \(A\) 的子序列的最大长度,使得任意两个相邻项之间的绝对差最多为 \(D\)

分析

\(f[i]\) 为以 \(A\) 中值为 \(i\) 为结尾的子序列的最大长度。则有:

\[f[i] = \max(f[j]) + 1 \]

其中 \(i - d \le j \le i + d\)

代码很容易出来:

for (int i = 1; i <= n; ++i) {
int x = 0;
for (int j = max(a[i] - d, 1); j <= min(a[i] + d, mx); ++j) x = min(f[j] + 1, x);
f[a[i]] = x;
}

\(mx\)\(A\) 中的最大值。

复杂度 \(O(n^2)\)。我们不能接受。

其中这一段:

for (int j = max(a[i] - d, 1); j <= min(a[i] + d, mx); ++j) x = min(f[j] + 1, x);

相当于在找一个区间内的 \(f\) 最大值。

但是,考虑到 \(f[i]\) 会变化。我们使用线段树板子维护这个最大值。

时间复杂度:\(O(n\log n)\)

代码

#include <bits/stdc++.h>
#define int long long
#define ls (p << 1)
#define rs ((p << 1) + 1)
using namespace std;
const int N = 5e5 + 5;
int n, d, f[N], a[N];
struct tree {
int l, r;
int mx;
} tr[N * 4];
void pushup(int p) {
tr[p].mx = max(tr[ls].mx, tr[rs].mx);
}
void build(int l, int r, int p) {
tr[p].l = l, tr[p].r = r, tr[p].mx = 0;
if (l == r) { return ; }
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
}
void change(int x, int p) {
int l = tr[p].l, r = tr[p].r;
if (l == r) {
tr[p].mx = f[x];
return ;
}
int mid = (l + r) >> 1;
if (x <= mid) change(x, ls);
else change(x, rs);
pushup(p);
}
int que(int L, int R, int p) {
int l = tr[p].l, r = tr[p].r;
if (L <= l && r <= R) return tr[p].mx;
int mid = (l + r) >> 1;
int res = -1e9;
if (L <= mid) res = max(res, que(L, R, ls));
if (R > mid) res = max(res, que(L, R, rs));
return res;
}
signed main() {
cin >> n >> d;
int mx = 0;
for (int i = 1; i <= n; ++i) cin >> a[i], mx = max(mx, a[i]);
build(1, mx, 1);
int ans = -1e9;
for (int i = 1; i <= n; ++i) {
int x = a[i];
f[x] = que(max(1ll, x - d), min(mx, x + d), 1) + 1;
change(x, 1);
ans = max(ans, f[x]);
}
cout << ans;
return 0;
}

本文作者:lucky_cloud

本文链接:https://www.cnblogs.com/luckycloud/p/18005312

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   lucky_cloud  阅读(22)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起