图论专题-专项训练:点分治
1. 前言
本篇博文是作者在学习点分治这一算法的时候做的一些题目的总结。
前置知识:点分治算法。
2. 练习题
题单:
P4178 Tree
考虑点分治。
这道题需要求的是路径长度小于等于 的情况,那么在点分治的 Solve
中我们需要做一点改变。
考虑建一棵值域线段树 用来维护所有当前已经出现过的路径,如果路径长度为 的路径出现过,那么就在值域线段树中对应的做一次单点 +1。
那么在点分治的过程中,考虑处理出所有能够出现的路径,假设当前子树处理出的路径为 ,那么对于所有 ,在线段树中查询 的和就可以了。
一个优化就是如果我们每次 Solve
都要重新建一棵值域线段树,那么建树复杂度就是 的,因此我们可以考虑采用区间推平的手段,在根节点处打一个 lazy_tag 用来标记当前这一段是否全部为 0(被推平),这样每一次我们只需要在根节点处推平一次就可以了,复杂度降至 。
Code:Github CodeBase-of-Plozia P4178 Tree.cpp
P2634 [国家集训队]聪聪可可
考虑点分治。
首先这道题一定要看一下样例解释,否则你会发现写完了根本调不出来。
这道题需要注意的几个点:
- 聪聪和可可是可以选两个相同的点的。
- 和 算作两个不同的点对()。
这样,总的点对个数是 ,我们只需要统计路径长度为 3 的倍数的路径就好。
对于 这样的点对,显然只有 对,在最后计算答案的时候加上就好。
在 Solve
中开一个 数组来统计,其中 表示模 3 为 的路径有多少条。
设当前子树统计结果是 ,那么这棵子树对答案的贡献就是 。
最后的答案就是 ,注意约分。
Code:Github CodeBase-of-Plozia P2634 [国家集训队]聪聪可可.cpp
P4149 [IOI2011]Race
考虑点分治。
emm如果你对点分治的套路足够熟悉的话这道题就是道裸题。
我们开一个桶 ,其中 表示路径长度为 的路径经过边数的最小值。
然后拿 做类似的玩意,转移就好了。
Code:Github CodeBase-of-Plozia P4149 [IOI2011]Race.cpp
3. 总结
点分治的题目通常都带有路径统计的特点,其考点通常在 Solve
函数上,如何设计 Solve
函数是关键。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)