点分治优化dp学习笔记
参考 : 猫锟的WC2018课件,Pepcy CHEN的HDU5909题解
对于一类树上的连通块dp问题,合并子树(卷积)的复杂度很高,但是插入一个点或者自己跟自己合并(不妨叫它是点积)的复杂度可以接受,那么可以使用点分治来优化。
一个(大概是这一类题中最常见的)例子是连通块上的背包问题。
具体地,如果要对于每个连通块求一个什么东西,我们先考虑强制这个连通块经过根,可以发现在这种情况下,如果一个点在连通块中,那么它的父亲必须也在。所以我们先从根top-down地dfs,对于每个点进行选/不选的决策,如果不选那就copy一份维护dp的数据结构;如果选那就操作维护dp的数据结构,然后dfs儿子;最后把两个数据结构拍起来(点积),我们就得到了这个点子树内的答案。当然最后要强制选重心。
每个连通块只会在第一次里面某个点被选为重心时统计一次,所以是正确的。
还是放道例题来具体说明罢。(然而只找到树上背包)
HDU5909 Tree Cuting
题意 :
考虑树上背包,我们显然可以设dp[u][i]表示以
发现儿子们的背包合并是个位运算卷积的形式,神们肯定会说我会FWT!好的那么你得到了一个
但是我不会FWT既然是讲点分治优化dp,肯定要用点分治的方法来做。
考虑这个背包卷积比较困难,但是"点积"非常简单(就是加起来),要插入一个点也非常简单。于是我们考虑点分治,对于一块 :
设dp[u][i]表示只考虑点