传送门
神题
o
r
z
orz
orz
- 点边容斥,即对每个点和每条边统计包涵它的个数,那么有简单的
O
(
n
2
)
O(n^2)
O(n2)
d
p
dp
dp,即以每一个点为根做一遍,注意到我们可以
u
p
a
n
d
d
o
w
n
up~ and~down
up and down 做
d
p
dp
dp,这样可以变成
O
(
n
L
)
O(nL)
O(nL),如下
f u j = ∏ ( f v j − 1 + 1 ) g u j = 1 + g f a j ∗ ∏ v ≠ x ( f v , j − 2 + 1 ) f_{uj}=\prod (f_{vj-1}+1)\\ g_{uj}=1+g_{faj}*\prod_{v\neq x}(f_{v,j-2}+1) fuj=∏(fvj−1+1)guj=1+gfaj∗v=x∏(fv,j−2+1)
其中 f f f 表示子树中深度 ≤ j \le j ≤j 的方案之和, g g g 表示子树上方距离 ≤ j \le j ≤j 的方案数之和
注意 f f f 可以长链剖分优化,合并的时候暴力乘,到末尾时对一段后缀有贡献,还需支持全局加1
后缀乘转成前缀除可以均摊 O ( n ) O(n) O(n)
注意到在求 g g g 的时候需要查 f f f,所以好像要可持久化,其实不然,我们求 g g g 的时候倒着做回去,用栈将操作回退,下面来看如何转移
对于重儿子的转移,可以暴力将轻儿子合并
对于轻儿子的转移,发现只需要知道 ( L − l e n , L ] (L-len,L] (L−len,L] 的状态,可以前后缀积做
逆元可以 O ( n ) O(n) O(n) 预处理 C o d e Code Code