bzoj 3653: 谈笑风生 可持久化线段树
题目大意
在一棵单位边权的有根树上支持询问:
给定a,k求满足下列条件的有序三元对的个数.
- a,b,c互不相同
- a,b均为c的祖先
- a,b树上距离<=k
题解
solution 1
首先我们知道,c一定在以a为根的子树内,否则不满足条件2
对于一个询问a,k,我们知道b一定在a的k步以内
所以我们把问题分为两部分:
- b是a的祖先
- a是b的祖先
对于问题一,我们容易发现答案即为\(min(dep_a,k)*(siz_a-1)\)
所以现在问题就在于我们如何处理问题2.
对于问题二我们在这里对c再进行讨论.
我们发现\(dep_a + k + 1\)是一个分界点
对于所有的\(c <= dep_a + k + 1\)我们发现对答案的贡献为\(\sum{dep_u - dep_a - 1}\)
对于所有的\(c > dep_a + k + 1\)我们发现对答案的贡献即为\(num*k\)
所以我们像七彩树一样将深度可持久化,对dfs序建立维护权和的线段树即可.
solution 2
前面的思路和solution1一样,只是在对问题二进行统计的时候,我们换一种思路.
我们这次选择讨论b的位置而不是去讨论c.
我们发现b一定在a的子树中深度不超过\(dep_a + k\)的位置
而对于每个b的位置,我们发现只要c为b的子树中的任何一个与b不同的点即可.
也就是说对于每个我们找到的b的位置,都有\(siz_b - 1\)的c与之对应
所以我们维护所有节点的\(siz - 1\)即可.(siz 表示子树大小).
也将深度可持久化,然后对dfs序建立维护(siz-1)的线段树即可.
代码不想贴.
人就像命运下的蝼蚁,谁也无法操控自己的人生.