首先我们要发现一个性质,对于每一棵树,我们换了一个根(把原本根的某个儿子(v_1)记成新的根)
我们记这个树的权值和为sum,每个子树的权值和为(S[i]),对于每次换根,受影响的(S[i])只有根本身和(v_1),并且满足:(S[rt]->sum - S[v_1]), (S[v_1] -> S[rt])
于是我们能惊人的发现:(sum (sum - S[i]) * S[i])是一个定值!!!
把他拆开:(sum * sum S[i] - sum S[i] ^ 2)
而我们要求的正是(sum S[i] ^ 2),于是我们只要维护(sum * sum S[i])
因为我们会修改权值,发现sum值很好维护,于是我们只需要维护(sum S[i])即可
我们假设以x为根,那么(sum S[i] = sum (dep[i] + 1) * val[i] = sum + sum dep[i] * val[i])
若我们不用重新求dep,柿子即化为:$sum S[i] = sum + sum val[i] * dis(i, x) $
这个式子就是动态点分治的模板了,但是我们其实还有一个问题:就是我们的那个定值((sum (sum - S[i]) * S[i]))要怎么求呢?
我们还是对每个点分开考虑:上述柿子的意义实际上是求出所有点的子树和 * (总的子树和 - 该点子树和)
我们分开考虑每一对点((i, j))的贡献,即两个点被分在不同集合的个数*权值之积
于是这个式子其实可以转化为(sum_{i = 1}^nsum_{j = i+ 1}^nval[i] * val[j] * dis(i, j))
把(val[i])提前,我们得到:(sum_{i = 1} ^ n val[i] * sum_{j = i + 1} ^ n val[j] * dis(i, j))
所以每一次修改(a[x] -> y),变化量即为((y - a[x]) *sum val[j] * dis(j, i))
这不就是(sum S[i])吗???
于是,我们就可以得到:
(sum - 1)直接维护,(sum S[i])用动态点分治来维护,后面那一堆我们可以根据(sum S[i])来维护,于是我们就做完了