原题链接
\(EDU\)出一道长链剖分优化\(dp\)裸题?
简化版题意
问你每个点的子树中与它距离为多少的点的数量最多,如果有多解,最小化距离
思路
方法1.
用\(dsu\ on\ tree\)做到\(O(nlogn)\)
方法2.
考虑\(dp\),也就是设\(f[u][d]\)表示以\(u\)为根的子树中有多少个点与它的距离为\(j\),则转移如下:
\(f[u][0]=1\),\(f[u][d]+=f[v][d-1]\)
发现可以直接通过把数组右移直接把一个儿子的信息继承过来,又因为转移是跟深度相关的,那么我们直接把长儿子的信息继承过来就好了,然后暴力合并短儿子的信息
这样的时间复杂度都是\(O(n)\)的,怎么证明?直接继承长儿子的信息通过指针可以做到\(O(1)\),然后每条长链只会在顶端被合并,而长链的长度和是\(O(n)\),于是总复杂度就\(O(n)\)啦
空间复杂度的证明同理
代码如下
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include