AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

洛谷 CF2006E. Iris's Full Binary Tree    原题链接    中等

作者: 作者的头像   Conan15 ,  2024-11-28 16:11:31 ,  所有人可见 ,  阅读 121


2


第一眼感觉动态加点维护答案是困难的,所以先来考虑一下静态问题。

一个较为简单的做法是枚举根在哪里,然后树的深度就是距离根最远点的距离。
而且还要满足可以构成二叉树,即需要满足如下两个性质:

  • 根节点的 $deg \leq 2$。
  • 其余节点的 $deg \leq 3$。($deg$ 表示节点度数)

然后我们再试图优化一下枚举根的过程,发掘一下性质,会发现:距离 $u$ 最远的点距离相当于 $u$ 先到达树的中心 $c$ 的距离再加上直径的一半。
证明如下:

显然最远点一定是直径端点之一。
那么相当于 $u$ 先从某个点 $v$ 进入直径,然后再走到更远的端点。
可以想到把从 $v$ 到中心 $c$ 点的路径合并进 $u$ 到 $v$ 的路径里,就变成了 $u$ 到中心 $c$ 再加上直径一半。

对于静态问题,直径的一半是常数,那么我们只要求出距离中心最近的 $deg \leq 2$ 的点即可,这一问题可以直接 dfs 用 $O(n)$ 的时间复杂度求解。


考虑如何解决动态问题。首先要解决动态求中心的问题,即动态维护直径。
容易发现加入一个节点 $u$ 的时候,只需要把它到直径两端点的距离分别的当前直径长度比较即可。中心可以倍增跳,不过有较为简单的维护方法。

观察到每次加入点,中心移动距离不会超过 $0.5$,即它要么在点上要么在一条树边的中心。
所以我们只要动态维护当前的树中心,维护方法是记录一个二元组 $(u,v)$,如果 $u=v$ 表示中心在点 $u$ 上,否则表示在 $(u,v)$ 边的中点上。

接下来就不能直接用 dfs 求最近点了,怎么办呢?
好像直接把树拍扁成 dfs 序然后线段树维护就好了呢。

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息