\(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