学会两种“把原操作换成边界信息”的建模:
前置:树形 DP、LCA 与子树、点双连通分量、圆方树、重心。
这两题的原始选择都大到无法枚举:前者是 $(n-1)!$ 种断边次序,后者是 $2^m$ 个边集。真正可压缩的不是“已做了哪些操作”,而是一个已封闭部分与未处理部分的接口。
对有根树的子树 $sub_x$,它与外界只有 $(x,fa_x)$。无论内部断边顺序多么复杂,这条父边上只会发生一次交换:一个原属于子树的权值离开,一个外来权值进入。
停顿:若记录出去的权值来自 $u$,进来后最终停在 $v$,是否还需要知道每条内部边的时刻?
外来权值是什么要由祖先状态决定。若把它也放进子树 DP,状态会多一维。因此本题把其路程费用延后到上层结算:DP 只保存已知原权值的费用。
在《城市建造》中,把 $G-E'$ 的每个连通块收缩。因为收缩图连通,每个块都含新边端点;块数又恰好等于端点数,所以每块恰有一个端点。于是,任意两个被选端点之间的每条路径都不能绕过未选点把它们重新连起。
在一个点双中选两个分属不同最终块的端点,点双内的绕行路径会迫使该点双整体参与分隔。这正是圆方树中“选中方点”的含义。被选方点必须在树上连通,删去它们后的圆点连通块就是原图最终连通块。
对有序点对 $(u,v)$ 令 $x=LCA(u,v)$。定义 $f[u,v]$ 为:删完 $sub_x$ 内所有边以及 $(x,fa_x)$,把原来在 $u$ 的权值送出子树,并使外来权值最后停在 $v$ 的最小已知代价。外来权值的走路代价不在此状态中结算。
$$ f[x,v]=\min_{(i,v)\in state(y)}(f[i,v]+d_x), $$
$$ f[u,x]=\min_{(u,i)\in state(y)}(f[u,i]+d_u+d_x(dep_i-dep_x)). $$
$$ f[u,v]= \min_i{f[u,i]+d_x(dep_i-dep_x)+d_u} +\min_j f[j,v]. $$
当 $u=x$ 或 $v=x$ 时,另一棵子树会再引入一个中间权值。但式子仍是“对每个中间端点预处理最小值,再扫描当前 LCA 的有序点对”。附件中的 minimum_one/minimum_two 正是这两层最小化。
根节点没有父边,因此不建造虚假外来权值,而是按一个/两个孩子单独收口。
对子树大小归纳。父边上只有一次交换,所以 $(u,v)$ 完整描述边界;二叉性保证节点周围的断边相对次序均在上述常数分类中。每个孩子状态由归纳假设最优,中间端点取最小便枚举了该次序下的全部可能。反过来,每个转移只拼接互不相交的孩子操作序列和当前节点的边,因此总能构造出合法次序。
有序点对总数 $O(n^2)$,每对只在 LCA 所在转移中常数次参与,时间 $O(n^2)$,空间 $O(n^2)$。$n=5000$ 时内存是主要瓶颈,附件使用一块连续 int64 存 DP。
prepare every ordered pair (u,v) in the bucket of LCA(u,v)
solve(x):
solve children first
if x is leaf: f[x,x] = weight[x]
if x has one child:
scan the child's ordered-pair bucket for the two parent-edge orders
if x has two children:
for each of the three parent-edge positions:
precompute first endpoint minima
precompute second endpoint minima
scan ordered pairs whose LCA is x and relax f
close the root separately because it has no parent edge
INF 要留出加法余量。state[x] 只保存 LCA 恰为 $x$ 的点对,否则同一点对会在多层被重复扫描。建圆方树:原顶点是圆点,每个点双是方点,方点连向该分量所有原顶点。以原圆点重心为根,size[u] 只统计子树中的圆点数。
固定 $s$。自底向上维护 ways[u]:子树内已封闭部分均能划成大小 $s$ 或 $s+1$ 的块,且唯一尚可向父亲连接的部分位于 $u$ 一侧。
size[child]<s 的子树只能与当前圆点合并,形成 tot。大于 $s$ 的子树必须内部合法,方案数相乘。对恰好为 $s$ 的子树,可能整体封闭,也可能成为连通分隔区继续的唯一方向;只有当当前未封闭部分尚只含该圆点时,才出现这个选择计数。$k=0$ 时只接受 tot==s。$k=1$ 时接受 s<=tot<=s+1;但若所有块实际都是 $s+1$,该方案也会在下一个 $s$ 里被统计,因此需减去“全部恰为 $s+1$”的 $k=0$ 计数。
最后不枚举 $s=1\ldots n/2$ 的全部值。令块数为 $t$,则 $s=\lfloor n/t\rfloor$;除法分块告诉我们这些商只有 $O(\sqrt n)$ 种。对 $k=0$,只有 $s\mid n$ 可行。
圆方树定理保证合法 $E'$ 与连通方点分隔区一一对应;删去该区域后,每个圆点块恰含一个 $V'$ 顶点,相邻分隔方点所对应的原边集也被唯一确定。固定 $s$ 后,对根子树归纳:小于 $s$ 的部分不得封闭,大于等于 $s$ 的部分必须由孩子状态完成,圆/方两类转移因而既不漏也不重。根状态成功恰等价于全树完成划分。
圆方树建造 $O(n+m)$。每个候选 $s$ 扫树一次,候选数 $O(\sqrt n)$,总时间 $O((n+m)\sqrt n)$,空间 $O(n+m)$。
T = block_cut_tree(G)
root T at an original-vertex centroid
candidate_sizes = distinct floor(n/t), plus divisor-related sizes
answer = 0
for s in candidate_sizes:
for u in reverse rooted order:
if u is a block node:
ways[u] = product of feasible large-child states
reject any child too small to form a component
else:
absorb every child subtree smaller than s into u
combine feasible large children
count the unique size-s child that may continue the separator
add root count; for k=1 subtract the all-(s+1) duplicate
subtree_size;数组容量要留到 $n+m$。两题都应先写一个可检查的状态语义,再写转移。P8294 可在断点中打印小树的 f[u,v],P9167 可打印每个候选 $s$ 的根计数。若样例错,先查“边界还没结算的量”,而不是先查取模或容器。