对于树上随机游走类题目,常见的解法是列方程组消元.暴力 Gauss 消元的复杂度不优秀,通常需要我们找出高效的递推算法.
对于一个方程组,如果它满足以下条件,那么其中所有元可以在 O(n) 的时间复杂度内被推出:
- 方程组的每个元一一对应树上某个节点.
- 树上的某个节点对应的元都和它邻域中的点对应的元有关.
设节点 u 对应的元为 xu,这些方程组通常具有以下形式:
xu=cu+v∈Nu∑ku,vxv
其中 Nu 指的是 u 的邻域,cu 是只和 u 有关的量,ku,v 是只和 (u,v) 这条边有关的量.
首先我们随便钦定一个根,记 p 是 u 的父亲.然后我们抛出这样一个结论:xu 其实只和 xp 有关.
感性理解这个结论.对于我们钦定的根和叶子,这个结论显然成立.对于其他的节点,考虑从叶子往上归纳,发现除了父亲的元都是已知项,容易得到结论成立.
那么,不妨设 xu=auxp+bu.记 Cu 表示钦定根后 u 的儿子构成的集合,尝试确定 au 和 bu:
xuxuxu(1−v∈Cu∑ku,vav)xuxu=cu+ku,pxp+v∈Cu∑ku,vxv=cu+ku,pxp+v∈Cu∑ku,v(avxu+bv)=cu+ku,pxp+xuv∈Cu∑ku,vav+v∈Cu∑ku,vbv=cu+ku,pxp+v∈Cu∑ku,vbv=1−v∈Cu∑ku,vavku,pxp+1−v∈Cu∑ku,vavcu+v∈Cu∑ku,vbv
观察形式可以得到:
au=1−v∈Cu∑ku,vavku,p,bu=1−v∈Cu∑ku,vavcu+v∈Cu∑ku,vbv
那么一次递推求出 au,bu,再次递推求出 xu 即可.
注意根对应的元和某些钦定了的元的取值.