南外集训 2024.2.14 T3
总觉得做过,但是就是想不起来在哪里做到的。
有两个人一开始在一棵树的根节点,每秒钟两人都可以向下走一条边。任意时刻,一个人可以瞬间移动到另一个人所在的点上。求遍历树上的所有点所需最短时间。
注意到我们只需要访问所有的叶子。我们把其中一个人叫人,另一个叫影子。
一个错误的想法:考虑一种状态设计:两个人同时在
这个想法是错误的,而且实际上是很不自然的:假设当前节点只有两个儿子,其中各有一个非常深的叶子,以及一系列很浅的叶子,那么正确的策略是保留两个最深的叶子,人一直不动,影子把所有浅叶子处理掉以后两人同时往两个深叶子走。而我们上面的策略实际上限制了进入一棵子树的时候必须要清理掉所有外面的叶子,只有子树上面的一小段单个儿子的链可以和外面的并行处理,而这是非常不自然的,并不能真正起到并行减少时间的效果,因为很容易通过在每个点旁边挂一些浅叶子来消除掉这种单个儿子的链,而直觉告诉我们最优解的策略不应该受此影响。
我们重新考虑整个问题。事实上我们并不是在一棵子树一棵子树地解决问题,而是通过每次确定一个特殊的子树并进入的过程,确定了一个特殊的根-叶子链,具体地也就是上面过程中人(而不是影子)所走的路径。每个不在这条链上的叶子都需要由影子在某个时刻出发去清理掉。假设已经选定了这个路径,我们可以将最小化总时间转化为最小化人等待影子的时间,进一步地,如果影子等待人,那么我们可以强制将它传送回来跟着人走。这样,我们只需要决定路径上的一系列关键点,在这些关键点,人等待影子清理一些叶子。影子每次会清理一个叶子,回到人,再清理,……,直到所有从这个关键点出发的叶子只剩最后一个(最优解中一定是最深的那个),此时人就开始向下走,且影子清理完这个叶子之前,人必须已经走到下一个关键点。那么注意到此时总时间实际上就是影子清理叶子的总时间,即所有被清理的叶子的深度和减去关键点的(带权)深度和,因为人永远在等待影子。
下面考虑一个
由于
注意到在上面的问题中我们使用了重链剖分,而转移合法性是深度相关信息,这简直倒反天罡。把重链剖分换成长链剖分,发现如果我们在向上寻找的过程中跳了长链,此时走到的第一个位置一定已经是合法转移了,于是不用再往上考虑。没跳长链的部分直接用单调栈。复杂度
我草,卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼卡常傻逼。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
2023-02-14 CF446C DZY Loves Fibonacci Numbers 题解和加强