解析丨不看头条底部的问题,你就点进来会一脸懵逼的

百家 作者:程序人生 2018-03-21 04:03:43

点击上方“程序人生”,选择“置顶公众号”

第一时间关注程序猿(媛)身边的故事



插图作者:maxwellthebeech


解析者:VCode28629——一名普通的高一OIer


解法


线段树启发式合并


结合10分的链的做法,我们可以像求lcs一样求一个最大点数小根堆。


我们先说一下40分的dp,f[i][j]表示以i为根的子树里形成的小根堆堆顶权值大于等于j的小根堆点数最大值,然后dp转移的时候,把儿子的f数组对应位加和,再把选自己产生的贡献算入即可。


我们考虑用数据结构优化这一过程,我们发现对于“以i为根的子树里形成的小根堆堆顶权值”只可能是"以i为根的子树中点的权值",那么我们利用这一点,用线段树存储“以i为根的子树里形成的小根堆堆顶权值”以及每个权值对应的小根堆点数最大值,但是我们发现我们这样做,对于上面那个dp转移的过程是很难在一个可行时间复杂度内实现的。


我们考虑改变存储方式,我们利用线段树存储“以i为根的子树里形成的小根堆堆顶权值”以及每个权值对应的"堆顶权值大于等于他的小根堆点数最大值",这个时候,我们在实现上述dp转移过程时,可以利用启发式合并,把点数较小的线段树暴力还原为数组集合,然后再利用这个数组去更新点数较大的线段树,最后把选自己产生的贡献算入。


我们dfs整棵树同时启发式合并,最后得到的根的线段树里的所有权值的"堆顶权值大于等于他的小根堆点数最大值"的最大值就是我们答案。


时间复杂度O(nlog^2n)

看完解析,欢迎留言讨论


- THE END -


点击图片get往期内容

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接