2026.9 树上专题做题记录

CF1844G Tree Weights

先给所有边的边权赋成 \(1\),然后 \(d_i \gets d_i - dis(i,i+1)\)

找到当前 \(d\) 的最小值,设其为 \(d_{x}\)。在 \(P(x,x+1)\) 上找一条边 \((u,v)\)(没被使用的),将 \(w(u,v)\) 设成 \(d_x+1\)。并对所有经过 \((u,v)\)\(P(y,y+1)\),将 \(d_y\) 减去 \(d_{x}\)。最后删去 \(d_x\),并将 \((u,v)\) 标记为已使用。

如果能给每对 \((i,i+1)\) 都分配一条边 \((u,v)\),那么一定是存在合法解的(不考虑 \(d_i < dis(i,i+1)\))。因为这样做保证了任意时刻 \(d_i\ge 0\),且轮到 \((i,i+1)\) 时让 \(d_i\) 变成了 \(0\)

尝试通过删叶子的方式来分配。以 \(1\) 为树根。随便找一个叶子 \(u\)

  1. 新建一个点 \(c\)
  2. \(u-1\) 不在 \(u\) 子树内。连边 \((c,u-1)\)
  3. \(u+1\) 不在 \(u\) 子树内。连边 \((c,u)\)

那么会得到若干条链。

对于某条链的前两个点 \((c,u)\),如果将 \(c\) 对应的边分配给 \((u,u+1)\),那么后面就都是确定的。

如果出现某条链 \(c\) 的数量与 \(u\) 的数量不同,显然就无解了。

这样分配的时间复杂度 \(O(n)\)。但是模拟的过程有点困难了。

原来不是这样做吗。

考虑以 \(1\) 为根。记 \(x_i\)\(i\)\(1\) 边权和。那么限制为:

  • \(x_i + x_{i+1}-2x_{\text{lca}(i,i+1)}=d_i\)

已知 \(x_1 = 0\)。从小到大枚举 \(i\),但问题是可能 \(\text{lca}(i,i+1) \ge i+1\)

注意到 \(x_{\text{lca}(i,i+1)}\) 前面有个 \(2\) 的系数,想到先对 \(2\) 取模。变成:

  • \((x_i + x_{i+1})\bmod 2=d_i\bmod 2\)

此时就可以推出 \(x_{2\sim n}\bmod 2\) 的值。再考虑对 \(4\) 取模,变成:

  • \((x_i + x_{i+1} -2(x_{\text{lca}(i,i+1)}\bmod 2))\bmod 4=d_i\bmod 4\)

同样可以推出 \(x_{2\sim n}\bmod 4\) 的值。

重复下去,就可以知道 \(x_{i}\bmod V\) 的值。当 \(V> x_i\) 时就不再需要继续推了。

最后再 check 一下是否满足边权都 \(\ge 1\) 即可。时间复杂度 \(O(n\log n + n\log V)\)

QOJ837 Giant Penguin

随便找棵 DFS 树然后点分治。

对于当前分治中心 \(u\),因为需要处理的信息必须跨过 \(u\),所以有用的非树边只有 \(O(k)\) 条(一条非树边贡献一个环)。而对于点 \(x\)\(y\) 的最短路,可以枚举一个必经点 \(c\),一定存在一个 \(c\) 使得 \(\text{dis}(x,y)=\text{dis}(x,c)+\text{dis}(c,y)\)。而这样的 \(c\) 只需要取 \(u\) 和这 \(O(k)\) 条非树边的端点。

那么以这 \(2k+1\) 个点为起点 BFS 得到最短路,查询时直接枚举这个 \(c\) 即可。

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

CF1458F Range Diameter Sum

树上圆理论。

  • \(f(u,r)\) 为距离 \(u\) 不超过 \(r\) 的点构成的邻域。
  • \(c(S)=f(u,r)\) 为包含点集 \(S\) 的最小邻域。这里令 \(x,y\)\(S\) 中最远两个点,\(u\)\(x,y\) 路径中点(可能是边的中点),\(d\)\(x,y\) 的距离。则 \(r = \frac{d}{2}\)。即 \(c(S) = f(u,\frac{d}{2})\)

有一些性质:

  1. 邻域 \(f(u_1,r_1)\) 包含邻域 \(f(u_2,r_2)\),当且仅当 \(r_1\ge r_2+\text{dis}(u_1,u_2)\)
  2. 对于合并两个点集 \(S_1,S_2\) 得到 \(c(S_1\cup S_2)\),有:
    1. \(S_1\) 包含 \(S_2\)\(c(S_1\cup S_2)=c(S_1)\)
    2. \(S_2\) 包含 \(S_1\)\(c(S_1\cup S_2)=c(S_2)\)
    3. \(S_{1}\)\(S_2\) 无包含关系。令 \(d = \text{dis}(u_1,u_2)\),则 \(c(S_1\cup S_2)=f(\text{move}(u_1,u_2,\frac{d-r_1+r_2}{2}),\frac{d+r_1+r_2}{2})\)。其中 \(\text{move}(u,v,w)\)\(u\)\(v\) 移动 \(w\) 的距离到达的点。
  3. 对于点集 \(S\),任意一个点 \(v\)\(S\) 中最远点的距离为 \(\text{dis}(u,v) + r\)\(c(S)=f(u,r)\))。

对于这题,考虑分治。

\(s(i)\)\(i\)\(\text{mid}\) 构成的点集。

如果已知 \(c(\{l,l+1,\dots,r\})=c(s(l)\cup s(r)) = f(u,R)\),那么 \(\text{diam}(l,r) = 2R\)

枚举 \(l\),维护指针 \(i,j\) 使得:

  1. \(r\in [\text{mid}+1,i]\) 均有 \(c(s(l))\) 包含 \(c(s(r))\)。设 \(c(s(l))=f(u,R)\),则 \(\text{diam}(l,r)=2R\)
  2. \(r\in [i+1,j]\) 均有 \(c(s(l))\)\(c(s(r))\) 无包含关系。设 \(c(s(l))=f(u_1,R_1),c(s(r))=f(u_2,R_2)\),则 \(\text{diam}(l,r)=R_1+R_2+\text{dis}(u_1,u_2)\)
  3. \(r\in [j+1,r_0]\) 均有 \(c(s(r))\) 包含 \(c(s(l))\)。设 \(c(s(r))=f(u,R)\),则 \(\text{diam}(l,r)=2R\)

先考虑维护出 \(c(s(i))\),首先 \(c(s(\text{mid}))=f(\text{mid},0)\)。以 \(c(s(l))\) 举例,设 \(c(s(l+1))=f(u,R)\)

  1. \(\text{dis}(l,u)\le R\)。则 \(c(s(l))=c(s(l+1))\)
  2. \(\text{dis}(l,u)>R\)。则 \(c(s(l)) = f(\text{move}(l,u,\frac{\text{dis}(l,u)-0+R}{2}),\frac{\text{dis}(l,u)+0+R}{2})\)

维护出 \(c(s(i))\) 后情况 \(1,3\) 都是简单的。情况 \(2\)\(R_1+R_2\) 也是简单的。对于 \(\text{dis}(u_1,u_2)\),相当于是查询某个点到当前所有关键点距离和,点分树即可。

那么只需要实现 \(\text{move}\) 函数,\(\text{dis}\) 函数,点分树和分治。为了方便计算 \(R\),可以给每条边中间加一个虚点,这样只需要最后答案除以 \(2\)

整体时间复杂度 \(O(n\log^2 n)\)

CF1168D Anagram Paths

考虑先判定一棵树是否是变为字母异位树。

  1. 所有叶子深度相同。
  2. \(cnt_{u,x}\)\(u\) 到子树叶子中 \(x\) 出现次数的最大值。那么需要满足 \(\sum\limits_{x='a'}^{'z'}cnt_{u,x}\le \text{mdep}(u)-\text{dep}(u)\)

容易发现,对于 \(f(c)\) 其实就等于 \(\text{mdep}(1)-\text{dep}(1) - \sum\limits_{x='a'}^{'z'}cnt_{1,x} + cnt_{1,c}\)

那么有:\(\sum\limits_{c=1}^{26}f(c) = 351(\text{mdep}(1)-\sum\limits_{x=1}^{26}cnt_{1,x})+\sum\limits_{x=1}^{26}x\times cnt_{1,x}\)

每个点上维护 \(cnt_{u,x}\)。那么修改点 \(p\)\(fa_p\) 之间的字符影响的就是一条 \(p\) 到某个祖先的链。二分这个祖先即可。然后就是对一条链的 \(cnt_{u,x}\) 增加或减少 \(1\)。最后整体维护全局最小值。需要 \(27\) 棵线段树。

时间复杂度 \(O(n|\sum|\log n + n\log^2 n)\)。这个也可以做到一个 \(\log\)

注意到因为叶子深度相同,所以一个点到根中有两个儿子的祖先只有 \(O(\sqrt{n})\) 个。那么暴力跳这些祖先的时间复杂度就是 \(O(n\sqrt{n}+n|\sum|)\) 的。

P10789 [NOI2024] 登山

先将 \(a\) 序列简化,即删去所有 \(p_{a_j}=a_{j-1}\)\(a_j\)。得到的应该是 \(x\)\(1\) 路径上的某些点,且深度单调递减。

再在 \(a_i\)\(a_{i+1}\) 中添加若干个休息的点,设 \(a_i\)\(a_{i+1}\) 中添加的最后一个休息点为 \(p\)(没有则令 \(p=a_i\))。考虑 \(a_{i+1}\) 的合法条件:

  1. \(d_{a_{i+1}}<\min\limits_{u\in P(p,a_{i})}^{}(d_u-h_u)\)
  2. \(d_p - r_{p}\le d_{a_{i+1}} \le d_{p} -l_p\)

定义状态函数 \(f_{u}\) 为从 \(u\) 出发的方案数。那么枚举 \(u\) 再枚举 \(p\),可以得到合法的下一个冲刺点范围,通过前缀和可以 \(O(1)\) 得到方案数之和。这样复杂度是 \(O(n^2)\) 的。

先考虑 \(l_i = r_i\) 怎么做。

对于 \(p\),设下一个冲刺点为 \(x\)。则 \(d_{p}-r_p \le d_x \le d_p-l_p\),也就是 \(d_x = d_p-l_p\)。此时满足 \(d_x < \min\limits_{v\in P(p,u)}^{}(d_v - h_v)\)\(u\) 应该是从 \(P(p,1)\) 的一段前缀。可以二分找到这个前缀的结尾 \(u_0\),那么所有 \(u\in P(p,u_0)\)\(f_u\) 都可以得到 \(f_{x}\) 的贡献。显然 \(d_x < d_{u_0}\) 所以不会转移出错。

具体做法就是 DFS 一遍,得到 \(f_{x}\) 之后将 \(x\) 子树中所有满足 \(d_{x} = d_{p}-l_p\)\(p\) 拿出来,对每个 \(p\) 找到这样的 \(u_0\),然后将 \(u\in P(p,u_0)\)\(f_u\) 都加上 \(f_x\)。复杂度 \(O(n\log^2 n)\)

如果 \(l_i \ne r_i\)

\(g_{u}=\sum\limits_{x\in P(u,1)}^{}f(x)\),相当于一个前缀和。对于 \(p\),设转移点为 \(u\)。条件变成 \(d_{p}-r_{p} \le d_x < \min(d_p-l_p+1,\min\limits_{v\in P(p,u)}^{}(d_v-h_v))\)。记 \(h(p,u)=\min(d_p-l_p+1,\min\limits_{v\in P(p,u)}^{}(d_v-h_v))\)。当 \(d_p-r_p \le h(p,u)\)\(f_u\) 得到 \(g_{\text{move}(p,h(p,u)-1)}-g_{fa_{\text{move}(p,d_p-r_p)}}\) 的贡献。其中 \(\text{move}(u,x)\)\(P(u,1)\) 中深度为 \(x\) 的点编号。

拆成两部分做。

\(g_{fa_{\text{move}(p,d_{p}-r_p)}}\) 就相当于 \(l_i=r_i\) 的情况。在得到 \(x = \text{move}(p,d_p-r_p)\) 的信息后枚举 \(p\)

\(g_{\text{move}(p,h(p,u)-1)}\) 这部分可以考虑放到 \(h(p,u)=d_v - h_v\)\(v\) 这里算。

  1. \(h(p,u) = d_p-l_p+1\)。找到深度最小的 \(u_1\),使得 \(h(p,u) = d_{p} -l_p+1\)。那么枚举 \(p\) 得到 \(u_0\) 后只需要与 \(u_1\) 取深度较大者即可。
  2. \(h(p,u)<d_p-l_p+1\)。考虑 \(i\)\(i\) 祖先中第一个满足 \(d_j -h_j < d_i - h_i\)\(j\) 连边,得到很多棵树。定义 \(cnt_v\) 为放到 \(v\) 这里来算的 \(p\) 的数量。不难发现 \(cnt_v\) 等价于新的树中 \(v\) 子树满足 \(d_p - r_p \le d_v - h_v < d_p - l_p+1\)\(p\) 的数量。由于新树上 \(d-h\) 是单调的,所以也可以对每个 \(p\) 二分找到这样的 \(v\) 所在链。树上差分就可以维护出 \(cnt_v\)。最后还是在得到 \(x\) 的信息后枚举子树中所有 \(d_v - h_v = d_x\)\(v\),让后对 \(u\in P(v, u_0)\)\(f_u\) 增加 \(g_{x}\times cnt_v\)

整体时间复杂度 \(O(n\log^2 n)\)

链加单点查不需要树剖。直接 dfn 序加就是 \(O(n\log n)\) 的了。。。

P16435 [APIO 2026 中国赛区] 集宝

\(f(u,r)\) 为与 \(u\) 距离不超过 \(r\) 的邻域。

对于暴力,显然就是每次走到 \(y\in f(a_{i+1},d_{i+1})\)\(\text{dis}(x,y)\) 最小的那个点上。时间复杂度 \(O(nq\log n)\)

发现对于相邻两个 \(f(a_i,d_i),f(a_{i+1},d_{i+1})\) 来说,如果 \(f(a_i,d_i)\cap f(a_{i+1},d_{i+1})\not= \emptyset\),将它们缩成它们的交 \(f(u,c)\) 对答案是没有影响的。

又发现这个合并顺序是没影响的,也就是如果 \(i\)\(i+1\) 合并之后不能再和 \(i+2\) 合并;如果 \(i+1\)\(i+2\) 合并之后不能再和 \(i\) 合并,这两种情况都是正确的。

那么考虑维护这些树上圆。具体地,维护 \(s,t,d,r\) 分别表示路径起点,路径终点,路径长度,经过的树上圆交的半径。

有定义:

  1. 对于一个点 \(u\)\(s = u,t=u,d=0,r=0\)
  2. 对于一个 \((a_i,d_i)\)\(s = a_i, t = a_i, d = 0, r = d_i\)

合并 \((s_1,t_1,d_1,r_1)\)\((s_2,t_2,d_2,r_2)\)\((s,t,d,r)\)

  1. 二者均为点。\((s,t,d,r) = (u,v,d_1+d_2+\text{dis}(t_1,s_2),0)\)。当 \(d_1 > 0\)\(u = s_1\);当 \(d_1 = 0\)\(u = \text{move}(t_1,s_2,r_1)\)。当 \(d_2 > 0\)\(v = t_2\);当 \(d_2 = 0\)\(v=\text{move}(s_2,t_1,r_2)\)
  2. 前者是点,后者是圆的交。
    1. \(t_1 \in f(s_2,r_2)\)\((s,t,d,r) = (s_1,t_1,d_1+d_2,0)\)
    2. \(t_1\notin f(s_2,r_2)\)\((s,t,d,r) = (u,v,d_1+d_2+\text{dis}(t_1,s_2)-r_2,0)\)。当 \(d_1 > 0\)\(u = s_1\);当 \(d_1 = 0\)\(u = \text{move}(t_1,s_2,r_1)\)。当 \(d_2 > 0\)\(v = t_2\);当 \(d_2 = 0\)\(v=\text{move}(s_2,t_1,r_2)\)
  3. 后者是点,前者是圆的交。
    1. \(s_2\in f(t_1,r_1)\)\((s,t,d,r) = (s_2,t_2,d_1+d_2,0)\)
    2. \(s_2\notin f(t_1,r_1)\)\((s,t,d,r) = (u,v,d_1+d_2+\text{dis}(t_1,s_2)-r_1,0)\)。当 \(d_1 > 0\)\(u = s_1\);当 \(d_1 = 0\)\(u = \text{move}(t_1,s_2,r_1)\)。当 \(d_2 > 0\)\(v = t_2\);当 \(d_2 = 0\)\(v=\text{move}(s_2,t_1,r_2)\)
  4. 二者均为圆的交。
    1. 前者包含后者。\((s,t,d,r) = (s_2,t_2,d_1+d_2,r_2)\)
    2. 后者包含前者。\((s,t,d,r) = (s_1,t_1,d_1+d_2,r_1)\)
    3. 二者相交。相交得到的圆的半径为 \(R =\frac{r_1+r_2-\text{dis}(t_1,s_2)}{2}\),圆心为 \(v = \text{move}(t_1,s_2,r_1 -R)\)。有 \((s,t,d,r) = (v,v,d_1+d_2,R)\)
    4. 二者不相交。可以看作移动到后者时就变成一个点了,因为如果不看作点可能还与后面的圆又有交,此时无法确定位置与距离,但基础暴力就是走到后者邻域中最近点,所以是可行的。\((s,t,d,r) = (u,v,d_1+d_2+\text{dis}(t_1,s_2)-r_1-r_2,0)\)。当 \(d_1 > 0\)\(u = s_1\);当 \(d_1 = 0\)\(u = \text{move}(t_1,s_2,r_1)\)。当 \(d_2 > 0\)\(v = t_2\);当 \(d_2 = 0\)\(v=\text{move}(s_2,t_1,r_2)\)

既然能合并,就可以直接倍增维护了。时间复杂度 \(O((n+q)\log^2 n)\)

CF1442E Black, White and Grey Tree

如果没有灰色点。

将同色连通块缩成一个点,得到一棵相邻两个点颜色都不同的树。

这个相当于选择一个点作为根,每次删掉所有叶子。那么操作次数就是到根距离的最大值加 \(1\)

这个选择直径中点是最优的,记 \(len\) 为直径长度(边数)。那么答案等于 \(\lceil\frac{len}{2}\rceil+1\)

如果有灰色点。发现灰色点是没有用的,可以直接删去。考虑证明:

如果灰色点有用,说明存在路径 \(u\to v \to w\),使得 \(u,w\) 不是灰色点,\(v\) 是灰色点。且 \(v\) 存在第三条边 \((v,k)\),满足在忽略 \(v\) 后得到的直径经过 \(u\to w\),但实际上 \(v\) 变成的颜色(\(v\) 不对这条直径产生贡献的颜色唯一)让真正的直径经过 \(u\to k\)

分情况讨论:

  1. \(u,w\) 同色。此时 \(v\)\(u\) 同色。
  2. \(u,k\) 异色。实际上 \(u,v\) 会缩成一个点,\(v\) 不产生额外贡献。
  3. \(u,k\) 同色。\(u,v,k\) 会缩成一个点,\(v\) 不额外产生贡献。
  4. \(u,w\) 异色。此时 \(v\) 可以与 \(u\)\(w\) 同色。
  5. \(u,k\) 异色。当 \(v,k\) 同色时不产生额外贡献。
  6. \(u,k\) 同色。当 \(v,k\) 同色时不产生额外贡献。

所以直径不会从 \(u\to w\) 变成 \(u\to k\)。那么删去 \(v\) 无影响。

并查集维护同色连通块即可。时间复杂度 \(O(n)\)

CF1712F Triameter

\(f(u)\)\(u\) 到最近一个叶子的距离。

考虑对于一个询问二分答案,问题变成判断是否存在一对点 \((u,v)\),使得 \(\text{d}(u,v)\ge mid\)

显然 \(\text{d}(u,v)=\min(\text{dis}(u,v),f(u)+f(v)+x)\)

枚举 \(u\),变成判断是否存在 \(v\),使得满足以下条件:

  1. \(f(v)\ge mid - x - f(u)\)
  2. \(\text{dis}(u,v)\ge mid\)

先一遍 DFS 预处理 \(f(i)\),并将 \(f(i)\) 从大到小排序。设排序后第 \(i\) 个为点 \(p_i\)。问题变成判断是否存在 \(i\in [1,k]\),使得 \(\text{dis}(p_i,u)\ge mid\)。直接维护直径。

使用 \(O(1)\) 查询的 \(\text{lca}\) 单次 check 就是 \(O(n)\) 的。

整体时间复杂度 \(O(n\log n + nq\log n)\)

考虑去掉二分。从前往后枚举 \(i\),同时维护当前的 \(ans\)。尝试将 \(ans\) 增加 \(1\)。此时可以用指针维护出满足 \(f(v)\ge (ans+1)-x-f(i)\) 的最大的 \(v\)(因为 \(ans\) 单调不减,\(f(i)\) 单调不增)。这样问题就又变成判断是否存在 \(j\in [1,v]\),使得 \(\text{dis}(p_i,p_j)\ge mid\) 了。

时间复杂度 \(O(n\log n + nq)\)

AT_arc087_d [ARC087F] Squirrel Migration

注意到让尽可能多的路径经过同一个点是不劣的。

比如要让尽可能多的路径经过 \(u\)。以 \(u\) 为根,若 \(u\) 的两个儿子 \(z_1,z_2\) 子树中存在两对点 \((x_1,y_1),(x_2,y_2)\),满足 \(x_1,y_1\in T(z_1);x_2,y_2\in T(z_2)\),将点对调整为 \((x_1,y_2),(y_1,x_2)\) 不劣。

注意到当 \(u\) 为树的重心时不存在绝对众数,此时一定可以让所有路径都经过 \(u\)

那么以树的重心为根。将根的每个儿子子树都染色成这个儿子的编号,令根为无色点。

问题变成给定每个点的颜色 \(col_{1\sim n}\),求排列 \(p_{1\sim n}\) 的数量。满足 \(col_{p_i}\ne col_i\)\(col_{p_i}=0\)(只有根的 \(col\)\(0\))。

考虑容斥。设 \(G(k)\) 为钦定 \(k\)\(i\) 满足 \(col_{p_i}=col_i\)\(col_{p_i} \ne 0\) 时的方案数。则答案等于 \(\sum\limits_{k}^{}(-1)^{k}G(k)\)

定义状态函数 \(f_{i,j}\) 为考虑完前 \(i\) 种颜色,有 \(j\) 个位置被钦定的方案数。记 \(cnt_i\) 为颜色 \(i\) 的数量。转移为:\(f_{i,j+x}\gets f_{i-1,j}\times \binom{cnt_i}{x}\times (cnt_i)^{\underline{x}}\)

最后 \(G(k) = f_{n,k}\times (n-k)!\)。时间复杂度 \(O(n^2)\)

P13695 [CEOI 2025] theseus

注意到 \(01\) 状态可以用来描述边的方向。

定义 \((u,v)\) 标记为 \(0\) 表示边 \(u\to v\);标记为 \(1\) 表示边 \(v \to u\)

\(T\) 为根跑 BFS 得到每个点到 \(T\) 的最短路 \(dis_i\)。按照 \(dis\) 从小到大分层。

考虑对于一条边 \((u,v)\)

  1. \(dis_u < dis_{v}\)。标记为 \(1\)
  2. \(dis_u > dis_v\)。标记为 \(0\)
  3. \(dis_u = dis_v\)。不太好处理。

如果 \(dis_{u}= dis_{v}\) 的边直接按照 \(u,v\) 大小连,这样可能需要 \(\min + O(n)\) 次查询。

考虑启发式合并。具体的,按照深度从大到小枚举,对于一条边 \((u,v)\)

  1. \(dis_{u}> dis_{v}\)。将 \(u\) 合并到 \(v\) 上面去。标记为 \(0\),并清空 \(u\)
  2. \(dis_u = dis_v\)。将小的合并到大的上面去,并清空小的。

这样从一个点出发,每次如果都能知道它下一次合并到哪个点,那么:

  1. 向上合并。显然走的最短路。
  2. 向左右合并。因为合并后 \(siz\) 至少翻倍,所以只会出现 \(O(\log n)\) 次。

但我们并不能存下每个点下一次合并到哪。

考虑对于同深度的边,按照 \(u\) 从大到小枚举合并。这样对于一条边 \((u,v)\),如果 \(dis_u = dis_v\),一定有 \(u > v\),且:

  1. \(siz_v = 0\)。说明之前一个更大的 \(u'\)\(v\) 合并了。如果走出边中编号最大的,是会走到 \(u’\) 或一个深度更小的点的。满足要求。
  2. \(siz_v>0\)。说明还没合并。此时 \(u\) 是最大的满足 \(dis_{u}=dis_v\) 的有边的点,走出边中编号最大的要么走到 \(u\) 要么走到深度更小的点。

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

CF1039D You Are Given a Tree

考虑对于一个 \(k\) 怎么做。

贪心地,维护 \(f_{u}\) 表示 \(u\) 会对父亲贡献多少个点。记 \(x,y\) 为儿子 \(f\) 的最大值与次大值,有:

  1. \(x+y+1\ge k\)\(f_u=0\),答案增加 \(1\)
  2. \(x+y+1<k\)\(f_u = x+1\)

注意到对于情况 \(1\),只会有 \(O(\frac{n}{k})\) 次。那么对于 \(1\le k \le n\),总次数是 \(O(n\log n)\) 的。

这启发我们放一起做。

维护 \(f_{u,k}\) 为当 \(k\) 为这个值时,\(u\) 会对父亲贡献多少个点。记 \(g(u)\)\(u\) 到最深的叶子路径上包含的点数。

不难发现,当 \(k \ge 2g(u)\) 时一定有 \(f_{u,k}=g(u)\)。那么考虑长剖。

对于一个 \(u\)

  1. 继承重儿子信息。

  2. 对于 \(u\) 的轻儿子,维护 \(h_k = (a,b)\) 表示 \(f_k\) 的最大值、次大值。因为是长剖,所以可以暴力求,只有 \(k\in (2g(u),2g'(u)]\)\(h_k = (g'(u)-1,g''(u)-1)\)。其中 \(g'(u)\)\(u\) 到次深的叶子路径上包含的点数,\(g''(u)\) 为第三深。

  3. 更新信息。

    1. 首先对于 \(k\in (2g'(u),1)\) 可以求出重儿子 \(f_{k}\),设 \(h_{k} = (a,b)\)。那么相当于取 \(f_k,a,b\) 的前 \(2\) 大作为 \(x,y\),然后暴力修改 \(f_{k}\)

    2. 其次对于 \(k\in (2g(u),2g'(u)]\),分两种情况讨论:

      1. \(f_k + a + 1 \ge k\)。相当于找到区间中所有满足 \(k-f_k \le a+1\)\(k\)。线段树维护区间 \(\min\) 即可。
      2. \(a+b+1\ge k\)。有 \(k\in (2g(u),\min(2g'(u),a+b+1)]\)

      显然,对于一个产生贡献的 \(f_k\),最多会被找到 \(2\) 次,不影响时间复杂度。最后再对 \(k\in (2g(u),2g'(u)]\) 执行 \(f_k\gets \max(f_k,a)+1\) 即可。

那么线段树需要维护:区间查询 \(\min\),区间 chmax,区间加 \(1\),单点修改。

整体时间复杂度 \(O(n\log^2 n)\)

CF2161F SubMST

枚举 \((u,v)\),考虑边 \((u,v)\) 什么情况下会在最小生成树上。

设子集为 \(S\),首先两个必要条件是:

  1. \(u,v\in S\)
  2. \(\nexists x\in S, \max(\text{dis}(x,u),\text{dis}(x,v)) < \text{dis}(u,v)\)

如果直接对这个算会将 \(\max(\text{dis}(x,u),\text{dis}(x,v))=\text{dis}(u,v)\) 的算重,但这个是小问题。

对于条件 \(2\),记 \(f(u,r)\) 为距离 \(u\) 不超过 \(r\) 的邻域,则需要满足 \(x\notin f(u,\text{dis}(u,v))\cap f(v,\text{dis}(u,v))\)。根据树上圆的性质,可知 \(f(u,\text{dis}(u,v))\cap f(v,\text{dis}(u,v))\) 也是一个邻域 \(f(w,r)\)

先在每条边上加个虚点,令实点为原树上的点。

考虑枚举圆心 \(w\),以 \(w\) 为根。枚举深度 \(r\),按顺序依次加入深度为 \(r\) 的实点。记 \(cnt_r\) 为深度不超过 \(r\) 的实点数量,\(c\) 为在加入当前实点之前已经加入的深度为 \(r\) 的实点数量。则贡献为:\((2^{(c-d)}-1) \times 2^{n-cnt_{r-1}-c-1}\times r\),其中 \(d\) 为与当前实点在 \(w\) 的同一儿子子树且已经加入的实点数量。 这样钦定了 \(\max(\text{dis}(x,u),\text{dis}(x,v))=\text{dis}(u,v)\) 时加入点的顺序,所以不会算重。

时间复杂度 \(O(n^2)\)

P11946 [KTSC 2025] 信竞天择 2 / evolution

因为是知道树的,所以考虑从下往上求解。

那么现在对于一个 \(u\),已知 \(u\) 每个儿子子树内部所有点的相对大小,现在需要合并所有儿子。

相当于现在合并两个大小分别为 \(a,b\) 的有序序列。

考虑两种做法:

  1. 直接归并 \(a,b\)。需要比较 \(|a| + |b| - 1\) 次。
  2. 因为 \(a,b\) 是有序的,所以可以考虑先找到 \(b_{\frac{|b|}{2}}\)\(a\) 中的位置。这样 \([1,\frac{|b|}{2})\)\((\frac{|b|}{2},|b|]\) 就被拆成两部分了。比较次数是 \(O(|b|\log\frac{|a|}{|b|})\) 的。

那么直接做,每次做比较次数小的那个就是对的。

P7563 [JOISC 2021] 最悪の記者 4 (Worst Reporter 4) (Day4)

\(i\)\(a_i\) 连边得到内向基环树森林。

对于非环上点,要求点权不小于父亲点权;对于环上点,要求点权相同。

注意到当确定了点权不变的点时,剩下的点一定可以满足条件。那么定义状态函数 \(f_{u}\) 为当 \(u\) 点权不变时,\(u\) 子树节省代价的最大值。有:

  • \(f_u = c_u + \sum\limits_{v\in son_u}^{}\max(f_{v}[h_v\ge h_u],g_{v,h_u})\)
  • \(g_{u,x}=\sum\limits_{v\in son_u}^{}\max(f_{v}[h_v\ge x],\max\limits_{y\ge x}^{}g_{v,y})\)

其中 \(g_{u,x}\) 表示选择 \(u\) 子树中若干个不交的子树,使得每个选择子树的根都被保留且点权不小于 \(x\)

直接线段树合并即可。需要维护:单点修改,合并,后缀 \(\max\)

对于一棵基环树,记环上点为 \(p_1,p_2,\dots,p_k\)\(sum\) 为基环树所有点 \(c\) 的和。分情况讨论:

  1. 环上的点都不保留。答案为 \(sum - \sum\limits_{i=1}^{k}\sum\limits_{v\in son_{p_i}}^{}\max\limits_{x}^{}g_{v,x}\)
  2. 有环上的点要保留。答案为 \(sum - \max\limits_{x}^{}(\sum\limits_{i=1}^{k}\max(f_{p_i}[h_{p_i}=x],\sum\limits_{v\in son_{p_i}}^{}\max\limits_{y\ge x}^{}g_{v,y}))\)

线段树合并时间复杂度 \(O(n\log n)\)

P10013 [集训队互测 2023] Tree Topological Order Counting

对于 \(u\) 计算答案,只需要满足 \(u\) 子树中的点都在 \(fa_u\) 之后就行了。

那么定义状态函数 \(f_{u,i}\) 为只考虑 \(u\) 子树外的点(包括 \(u\))且 \(u\) 的相对大小为 \(i\) 时的方案数。

\(g_u = siz_u!\prod\limits_{v\in T(u)}^{}\frac{1}{siz_v}\)。那么有:

  • \(ans_u = \sum\limits_{x = 1}^{n}b_{x} \times f_{u,x}\times \binom{n-x}{siz_u-1}\times g_u\)

对于转移,有:

  • \(f_{u,i} = \sum\limits_{j<i}^{}f_{fa_u,j}\times (\prod\limits_{v\in son_{fa_u}\land v\ne u}^{}g_v)\times ((n-j-siz_u)! \prod\limits_{v\in son_{fa_u}\land v\ne u}^{}\frac{1}{siz_v!}\times \frac{1}{(n-siz_{fa_u}+1-j)!})\)

时间复杂度 \(O(n^2)\)

QOJ9700 英杯

定义状态函数 \(f_{u,x,y,0/1}\)\(u\) 子树,有 \(x\) 个点是局部最小值,且 \(a_{fa_u}\)\(u\) 小或大,\(a_u\) 的相对大小为 \(y\) 的方案数。

维护一个 \(g_{i,x,y,1/0}\) 表示考虑完前 \(i\) 个儿子,一共有 \(x\) 个局部最小值,相对大小为 \(y\)\(u\) 是否比前面的儿子都小的方案数。

设当前儿子为 \(v\),则:

\[g_{i,x+x',y+c,0}\gets g_{i-1,x,y,0}\times f_{v,x',y',[y'\le c]}\times \binom{y-1+c}{c}\times \binom{siz-y+siz_v-c}{siz_v-c}\\ g_{i,x+x',y+c,0}\gets g_{i-1,x,y,1}\times f_{v,x',y',1}\times \binom{y-1+c}{c}\times \binom{siz-y+siz_v-c}{siz_v-c}[y'\le c]\\ g_{i,x+x',y+c,1}\gets g_{i-1,x,y,1}\times f_{v,x',y',0}\times \binom{y-1+c}{c}\times\binom{siz-y+siz_v-c}{siz_v-c}[y'>c] \]

其中 \(siz\) 为前 \(i\) 个儿子子树大小和加 \(1\)。初始化 \(g_{0,0,1,1}=1\)

再对 \(u\) 是否是局部最小值分类讨论:

  1. \(u\) 不是局部最小值。\(f_{u,x,y,1}\gets g_{|son_u|,x,y,0},f_{u,x,y,0}\gets g_{|son_u|,x,y,0/1}\)
  2. \(u\) 是局部最小值。\(f_{u,x+1,y,1}\gets g_{|son_u|,x,y,1}\)

特别的,当 \(u\) 是根时,有:

  1. \(ans_{x}\gets g_{|son_u|,x,y,0}\)
  2. \(ans_{x+1}\gets g_{|son_u|,x,y,1}\)

直接做时间复杂度 \(O(n^4)\)

直接卷做到 \(O(n^3\log n)\)

P10064 [SNOI2024] 公交线路

考虑判定一个集合 \(S\) 合不合法。

对于一个叶子 \(x\),记 \(T_x\) 为与 \(x\) 有边的点集合。则应该满足 \(\bigcap\limits_{x \text{ is leaf}}^{}T_x \not= \emptyset\)

相当于形成一个连通块。点减边容斥,有:

  1. 对于一个点 \(u\)。如果对所有叶子 \(x\) 均满足:\(S\) 中存在同时经过 \(x,u\) 的路径 \(P\)。则贡献 \(1\)
  2. 对于一条边 \((u,v)\)。如果对所有叶子 \(x\) 均满足:\(S\) 中存在同时经过 \(x,u,v\) 的路径 \(P\)。则贡献 \(-1\)

答案即为所有贡献之和。

先做点的贡献。

路径两端都是叶子不太好做,考虑容斥。设 \(G(u,x)\) 为钦定 \(x\) 个叶子在 \(S\) 中不存在同时经过 \(x,u\) 的路径 \(P\) 的方案数。则合法方案数为 \(\sum\limits_{x}(-1)^xG(u,x)\)

叶子被分进若干个子树和 \(u\) 子树外。钦定子树外的叶子一定经过 \(u\),对子树内的容斥。设 \(v_i\)\(u\) 的第 \(i\) 个儿子,\(leaf_x\)\(x\) 子树叶子数量,\(siz_x\) 为子树大小。定义状态函数 \(f_{i,j}\) 为考虑完前 \(i\) 个儿子子树,钦定 \(j\) 个叶子不经过 \(u\) 的方案数。有:

  • \(f_{i,j+j'}\gets f_{i-1,j}\binom{leaf_{v_i}}{j} 2^{(\sum\limits_{k\le i}^{}siz_{v_{k}} - j)(siz_{v_i}-j)}\)

那么 \(u\) 的贡献为 \(2^{\binom{n-siz_u}{2}+\sum\limits_{v\in son_u}^{}\binom{siz_v}{2}}\sum\limits_{x}^{}(-1)^x f_{|son_u|,x}2^{(siz_u-x)((n-siz_u)-(leaf-leaf_u))}(2^{siz_u-x}-1)^{leaf-leaf_u}\)

时间复杂度 \(O(n^2)\)

再做边的贡献。

枚举边 \((u,fa_u)\)。还是钦定子树内有 \(x\) 个点不经过这条边。

贡献为 \(-2^{\binom{siz_u}{2}+\binom{n-siz_u}{2}}\sum\limits_{x}(-1)^x \binom{leaf_u}{x}2^{(siz_u-x)((n-siz_u)-(leaf-leaf_u))}(2^{siz_u-x}-1)^{leaf-leaf_u}\)

时间复杂度 \(O(n^2)\)

posted @ 2026-09-08 11:37  harmis_yz  阅读(9)  评论(0)    收藏  举报