[JOISC 2021 Day3] ビーバーの会合 2

前言:

离联合省选还有 28 天,模拟赛 40min 把这题切了睡了一上午。


来讲个有点异类,不用点分治的单 \(\log\) 做法。

首先我们观察发现在奇数的时候答案是 \(1\),偶数的时候答案才有可能不是 \(1\),分析一下为什么是这样:

这种问题一般考虑边的贡献,对于一条边,假设它的一侧有 \(x\) 个人,另一侧有 \(i-x\) 个人,则我们可以通过把集合地点定在较小的那一侧以做到 \(\min(x,i-x)\) 的贡献,如果定在另一侧则会是 \(\max(x,i-x)\),这样不会使结果变劣当且仅当 \(x=i-x=\frac i 2\),也就是说两侧的点是一样多的时候才可以移动到另一侧。

继续观察一下就是对于这个无根树,选两个不交,大小相等的子树,那么可能的集合地点就是两个顶点的路径上的所有点。

所以问题就被转化成了对于每个 \(i\) 选两个不交,大小相等的子树使得它们的顶点之间的距离尽可能远。

考虑给树定一个根,然后就需要处理两种情况,第一种是两个没有包含关系的子树之间,第二种是一个子树和另一个子树的补树。

然后枚举 \(i\),只考虑这些 \(siz_u \geq i\) 的点两两之间的最长的路径,经典地,像 dfs 序求 LCA 一样的方式将路径看成三元组: \(u\to l\to v\),则长度为 \(d_u+d_v-2 d_l\) 其中 \(d_x\) 表示 \(x\) 的深度,这个东西可以看作 \(a_x+b_y+a_z (x<y\leq z)\) 的最值,可以用线段树维护,将 \(b_x\) 设成 \(-d_x\)\(a_x\) 设成负无穷或者深度即可。

然后就是一个点和它的祖先的补树的情况,这种情况很简单,直接在加入某个点的时候查下它子树内已经加入的点或者祖先中已经加入的点的最值就行了。

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

posted @ 2023-03-03 15:22  寂静的海底  阅读(125)  评论(0编辑  收藏  举报