一、理解
先从一个典型的例题开始,树的每个节点都有一个颜色,求某个节点v的子树中颜色c的个数。暴力的话,就是对于每一个节点都统计一下子树中颜色c的个数,复杂度为。现在,我们来优化。可以发现我们做了很多重复的工作,如果能利用一些工作的结果那就好了。这里要引入轻/重儿子的思想(好像就是轻重链,树链剖分。。。。),可以证明从整棵树的根节点到树中任意一点的路径上最多有 条轻边。(相关定义及证明请参考博客:https://www.cnblogs.com/zwfymqz/p/9683124.html)。所以我们把重儿子的贡献保存,每次暴力计算轻儿子以及自己的贡献即可。每个轻儿子最多会被暴力枚举次,所以时间复杂度为。
二、套路
基本套路就是,对于u的子树:
1、计算所有轻儿子v的答案,不保存。
2、计算重儿子son[u]的答案,并保存贡献。
3、暴力计算本节点u及所有轻儿子v对答案的贡献。
4、加上重儿子son[u]的贡献,得到该子树u的答案。
5、如果u不是其父亲的重儿子,即不需要保存贡献,清除其子树的贡献。
这种题一定要转化为考虑每个节点的子树对答案的影响,如果是询问就转化为对子树的询问。
三、例题及题解
3、埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B 合约数 题解
5、HackerEarth, The Grass Type 题解
6、CF 246E Blood Cousins Return 题解
9、CF 1009F Dominant Indices 题解
特推博客:https://codeforces.com/blog/entry/44351
其他参考博客:
https://www.cnblogs.com/zwfymqz/p/9683124.html
https://baijiahao.baidu.com/s?id=1613444794783555531&wfr=spider&for=pc