跳转至

Black White Tree

题意

有一棵 \(n\) 个点的树以及一个参数 \(k\),结点依次标号 \(1, \dots, n\)。结点 \(i\) 有权值 \(w_i\),其深度为 \(d_i\)

初始时每个结点均为白色,可以选某些点染黑,但需要满足以下条件:

  • 称黑色结点 \(u, v\) 是连通的当且仅当 \(u\)\(v\) 路径上的结点均为黑色;
  • 对于任意连通结点 \(u, v\),均要求 \(|d_u-d_v|\leq k\)

最大化黑色结点权值之和。

\(1\leq n \leq 10^6\)\(0\leq k\leq 10^6\)\(0\leq w_i\leq 10^9\)

题目来源

@Serval

题解

Hint 1

\(k = 0\) 的特例是最大独立集。

Hint 2

\(k = 1\) 的特例也可以沿用 \(k = 0\) 的做法 DP 解决。

Hint 3

\(f_{u,i}\) 表示当前考虑以 \(u\) 为根的子树,\(u\) 联通的结点与 \(u\) 深度差最大为 \(i - 1\) 时黑色结点权值和的最大值。特殊地,\(f_{u,0}\) 表示结点 \(u\) 为白色。 直接 DP 是 \(O(nk)\) 的,有什么办法优化吗?

Hint 4

一种优化树上 DP 的方式是长链剖分。

Hint 5

\(v\) 取遍 \(u\) 的子结点,容易写出状态转移方程: $$ \begin{aligned} f_{u,0} &= \sum_v \max_{0\leq j\leq k+1} {f_{v,j}} \\ f_{u,i} &= w_u + \sum_v \max_{0\leq j\leq i-1} {f_{v,j}} \qquad (i > 0) \end{aligned} $$ 转移时需要取前缀最大值,如何优化?

Hint 6

不妨设 \(g_{u,i} = \max_{0\leq j\leq i} \{f_{u,j}\}\),有什么效果吗?

Hint 7

我们只需要维护 \(g\) 而不需要维护 \(f\) 即可完成 DP! $$ \begin{aligned} g_{u,0} &= \sum_v g_{v,k+1} {f_{v,j}} \\ g_{u,i} &= w_u + \sum_v g_{v,i-1} \qquad (i > 0) \end{aligned} $$ 但是考虑这样一种情况:长度为 \(k\) 与长度为 \(1\) 的两条链合并,长度为 \(1\) 的链对 \(g\) 均有贡献。

Hint 8

根据 \(g\) 的定义,\(g_{u,i}\)\(i\) 递增单调不减。

Hint 9

可以对单调序列作差分,通过维护差分序列而维护单调序列。

Solution

定义 \(g_{u,i}=\max_{0\leq j\leq i} f_{u,i}\)\(g_{u,i}\) 单调不降是显然的。考虑转移时需要的操作:

  • 查询单调序列最大值(查询 \(g_{u,k+1}\)
  • 删除单调序列末尾元素(删去 \(g_{u,k+2}\) 以保证单调序列中所有值合法)
  • 合并两个单调序列,对应位置相加(轻儿子 DP 值向父结点合并)
  • 单调序列整体加一个非负数(对于 \(0<i\leq k+1\)\(g_{u,i}\) 加上 \(w_u\)
  • 单调序列前端添加元素,并对后面所有项取 \(\max\)(加入 \(g_{u,0}\)

可以对单调序列作差分,并维护差分序列非 \(0\) 的项。额外维护差分序列和即可查询序列最大值,删除差分序列的末尾元素即可删除单调序列末尾元素,差分序列首项加法即可单调序列整体加法,这一部分时间复杂度 \(O(1)\)

合并两个单调序列只需提取两个差分序列的公共前缀,双指针合并后再与非公共后缀拼接。两个长度为 \(l_1,l_2\) 的单调序列合并的时间复杂度 \(O(\min\{l_1,l_2\})\)

在单调序列前端添加元素需要在差分序列前端添加元素,并删除或修改后面连续一段的差分值以取 \(\max\),由于一个结点最多加入一个差分值(\(g_{u,0}\)),这一部分均摊时间复杂度 \(O(1)\)

时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)