又学了一种什么题都是模板的算法, 深感药丸
沙茶的 点分治不详解
点分治, 可以用来找满足某种约束条件的路径的条数\(or\)经过最多\(or\)最少边的路径数等等
具体思想和实现起来就是计算和利用子树的计算来去重
我们考虑以当前节点为根的子树对答案的贡献:
- 以当前节点为起点的路径组合的贡献
- 在当前节点子树中的路径的贡献 (不经过当前节点的路径的贡献, 即忽略的路径 需要加上)
- 以某棵以\(x\)节点为根的子树中不符合要求, 而重复经过路径\(x \rightarrow dq \,\, \&\& \,\, dq \rightarrow x\)后"符合要求"的路径 (即需要去重的路径)
这样就可以直接到子树中递归分治了
然而我们发现, 如果这样搞的话, 一些奇怪的数据可能把我们卡成\(n ^ 2\), 然而你不是AH-mhr, 你没有高超的暴力技巧, 于是我们每次应该找树的重心, 每次删除重心并递归重心的子树, 这样一次递归毕然会使节点数量减少一半, 复杂度为\(\mathrm O(n\lg n \cdot\)每次递归操作的复杂度\()\)
这玩意还是看代码比较得劲...
沙茶一不小心水过的 超SB模板题
poj1741 Tree
点分模板题, 没啥说的
- 漏了
i < j
WA了好几发... - 不能只在
init_size()
之前memset
一次maxside
数组...耗时又大又会出问题...而是应该直接在每次递归到当前节点的时候就赋值为0
沙茶的 代码
1 |
|
聪聪可可
也是裸题吧...据说有dp做法就跟着写了一发,
我一开始胡的dp和点分治差不多,
然后一直WA...也不知道为啥...后来看远古神犇blog,
改成po姐的写法...过了...我感觉其实差不多啊,
有没有人愿意来看看啊qwqwqwqwq
细节就是一开始写点分治的时候忘了 如果两条膜3为0的路径加起来路径和膜3也是0...调了好半天才过的样例...
还有就是一条路径可以正反选两遍非常恶心...
沙茶的 代码
点分治写法
1 |
|
dp写法
AC
用dp写果然短了不少
1 |
|
WA
蜜汁WA了...qwqwqwqwqwq有人愿意看看嘛 /kel
1 |
|
Race
沙茶的 代码
犯了一些sb错误...比如
- 递归找根没有记录返回的根(?????)直接把
b[i].to
当成子树的根了(????)... - 计算
maxside
数组居然用size[root] - maxside[dq]
, 应该是size[root] - size[dq]
- 计算
cnt
的时候把i
和j
全写成了i
... - 在子树中计算去重的时候没有考虑到初始的时候来回已经经过了两条边, 也就是要从2开始计算边数
然后你就有95分辣! IOI的题95分是不是很激动?
一开始以为是哪里的细节出了问题, 静态查了半天 + 胡乱搞反例都没啥用, 最后还是看了po爷爷的blog...
还有一个问题...其实你的算法整个都是有问题的...
就是...可能会出现dis
数组相等的问题,
所以不能直接移动j
指针; 而是应该对于每一个i
,
都备份一个j
并移动, 对于下一个i
从头开始判断,
复杂度...不是很懂...不过大概不是\(\mathrm
O(n)\) 吧...
最后....卡常让人怀疑人生...最后bzoj还是没过...不过某谷还是能过的...
又: 某谷上这个题...是黑的...被我用三个小号...刷成紫题了...Emmm...
你们加油把他搞成红的啊
卡常前
1 |
|
卡常后
1 |
|
感觉文化课彻底凉了...
By 吃枣药丸的 Cansult