2025 刷题计划 - 树上问题

2025 刷题计划 - 树上问题

A. CF609E Minimum spanning tree for each edge

几个月前也许还觉得有点难,现在已然成为傻逼题。

B. CF70E Information Reform

树形 DP 好题。一开始想成了换根,想了 2h 发现不太可做,主要是不会设计状态。套路地将节点 \(u\) 选还是不选设入状态这种方法是不可做的。

观察到 \(n\le180\),在树上问题中这个数据范围不多见,大抵是一个 \(O(n^3)\) 的算法,那么首先不管用 Floyd 还是 DFS 求出两点间距离记作 \(\text{dis}(u,v)\) 是容易的。

那么状态设计就是本题的难点,首先得到一个极为重要的引理如下。这个引理告诉我们,对于一个节点 \(u\) 所辐射的点形成一个连通块。那么既然形成了一个连通块了,就可以将问题转化为:把树分为若干个连通块,每个连通块选择一个区域信息中心的代价。

引理:设 \(t_i\) 是离节点 \(i\) 最近的区域信息中心。对于树上两点 \(u,v\),若 \(t_u=t_v=k\),则在 \(u\to v\) 路径上的所有点 \(w\) 都满足 \(t_w=k\)

那么这个问题就简单了,对于每个连通块在其根部计算贡献,设 \(f_{u,j}\) 为以 \(u\) 为根的子树中 \(t_u=j\) 的最小代价,则有

\[f_{u,j}\gets f_{u,j}+\min_{v\in\text{son}(u)}\{f_{v,k},f_{v,j}-K\} \]

实际实现中,我们只需要再记录一个使 \(f_{u,j}\) 最小的 \(j\),记作 \(g_u\),就可以把上述转移方程优化到 \(O(n^3)\)

输出方案也是容易的。

C. P7359 「JZOI-1」旅行

暴力 DP 是容易的,复杂度 \(O(n^2)\)。想要优化,因为是无根树,我们就得开两个 DP 数组,一个记录他到他爸,一个记录他爸到他的答案。

我们现在的诉求是快速求出树上一段路径的 DP 值。可以尝试倍增或树剖套广义矩阵乘法。广义矩阵乘法应该是动态 DP 里面要用的,所以这题也算半个动态 DP。

广义矩阵乘法公式为:

\[C_{i,j}=\min\{A_{i,k}+B_{k,j}\} \]

实际上就是把原 \(\sum\) 改为 \(\min\)、原 \(\times\) 改为 \(+\)

考虑如何构建矩阵。写出转移方程:

\[\begin{aligned}f_{u,0}&\gets\min(f_{v,0},f_{v,1})+a_v\\f_{u,1}&\gets\min(f_{v,0}+L,f_{v,1})+a_v\pm z_v\end{aligned} \]

所以矩阵就长这样:

\[\begin{bmatrix}f_{u,0}&f_{u,1}\end{bmatrix}=\begin{bmatrix}f_{v,0}&f_{v,1}\end{bmatrix}\times\begin{bmatrix} a_v&a_v\pm z_v+L\\ a_v&a_v\pm z_v \end{bmatrix} \]

手模一下。然后倍增就正常预处理,注意乘法顺序

D. P9399 「DBOI」Round 1 人生如树

纯纯诈骗题。就是一个简化版的汽油价格

你会发现我们只要搞出来两个数组的哈希,如果合法,它们的哈希值之差就应该是类似 \(\dots54321\) 这种(看作 \(P\) 进制,其中 \(P\) 是哈希底数)。然后你发现这个东西纯纯可以预处理。又因为有单调性直接二分答案。

剩下的不就全是那道题的套路了么,什么树状数组、树剖给它一搞就完了。

什么?你担心怎么修改?修改根本不影响原来的答案!所以把询问离线,全修改完之后再做。反正这题又不强制在线。

诈骗题。根本不用什么差分。做题要懂得想以前的套路。

E. CF1023F Mobile Phone Network

和 A 一样的傻逼题。一个数组开小导致的 WA 调了 1h,最后还是 CF 的 AI 告诉我的。

F. CF293E Close Vertices

点分治维护树上二维偏序的板题。套路依然是一维用排序解决,另一维用树状数组解决,保证树状数组里的值都满足第一维偏序的前提下维护第二维偏序。

但这样的话同一子树内的点会算重,所以需要容斥一下。我的第一种写法在 CF 上评测 WA#6,但本地半个小时拍不出错误。换一种写法一遍过。能过的写法是在 calc 函数中容斥,每遍历一个儿子容斥掉当前子树,最后把所有子树的答案搂一块加上。divide 函数永远只负责分治,不负责统计答案;dis 数组里不能含有 0,而是最后把树状数组里剩余的再加上。

G. CF1521D Nastia Plays with a Tree

傻逼贪心。套路依然是先断边再连边。为了使总断边次数最小,优先断掉与父亲的边(因为这样就能少断一个儿子)。

树上贪心一定自下而上,默认处理完了所有子树后再考虑当前节点。

树上贪心一定自下而上,默认处理完了所有子树后再考虑当前节点。

树上贪心一定自下而上,默认处理完了所有子树后再考虑当前节点。

H. AT_arc165_e [ARC165E] Random Isolation

看起来很典的 DP 题,但并不简单。

由于期望的线性性,套路地把期望拆到每个点上。设 \(E(x)\) 表示点 \(x\) 产生贡献的概率,则答案显然就是 \(\sum E(x)\)。至于求这个 \(E(x)\),把操作转化为:对于随机的长度为 \(n\) 的排列 \(p\),按照 \(p_1,p_2,\dots,p_n\) 的顺序依次考虑 \(p_i\) 所在连通块的大小,根据题目所给的方法进行操作。易得这样转化的做法正确,因为无效点一旦删去不会对之后答案产生影响。

那么,点 \(x\) 产生贡献当且仅当它所在的连通块大小 \(>k\),现在问题变为,统计每个这样的连通块出现的概率

设连通块大小为 \(x\),与该连通块相连(不属于该连通块)的点的个数为 \(y\),放到排列 \(p\) 上就是 \(\boldsymbol x\) 个节点在 \(\boldsymbol y\) 个节点之后的概率,易得这个概率为 \(\dfrac{x!y!}{(x+y)!}\)

那么现在只剩下最后一个任务就是统计每一种 \((x,y)\) 的连通块有多少个,到这一步就可以树上背包解决了。总复杂度 \(O(n^2k^2)\)


后面两道一道原,一道傻逼莫队,没了。

posted @ 2025-02-10 15:02  Laoshan_PLUS  阅读(12)  评论(0)    收藏  举报