首先考虑暴力,显然,这个东西答案就是每条边的贡献的和,每条边的贡献就是这条边两边分别选的有点的方案数量。写出来就是
totk−sizk−(tot−siz)k注意到这个题的性质:每个点的子树内点的值都是 u 到某个值的一段区间。容易发现画出来后需要考虑的叶子总是这样的一些子树(图中橙色的子树)。
我们考虑除开 L 和 R 的橙色子树。这些子树内的点的子树都必然会选完所有叶子。如何快速的查这些点向上的边的贡献?明显 sizk,totk 很容易计算,考虑怎么算最后那个式子。我们考虑对它二项式定理展开:
k∑i=0(ki)totk−isizi对于这些点我们预处理出它们的 sizi 的和,再做前缀和即可。
考虑 L,R 的最近的叶子。这些点向上一直到 LCA 形成的链就是叶子不一定全部选完的链。我们单独考虑这些位置的贡献。
比如考虑左边 L 到 LCA 这条链,相当于是固定了每个位置的左端点,右端点就是子树内的右端点。
我们写成式子,就是
(Sr−SL−1)k+(tot−(Sr−SL−1))k其中 S 是前缀的叶子个数。
我们换个方式拆成二项式定理
maroonrkSir(−SL−1)k−i(tot+SL−1)i(−Sr)k−i这两个东西分别对应左右分别拆成的二项式定理。
所以我们应当预处理出 (Sr)k−i 在链上的和,剩下的 (−SL−1)k−i,(tot+SL−1)i 对于同一个询问都是常量。
另一条链类似整即可。
cpp
1 |
|