题意
给定一颗有根带权树,记\(LCA(u,v)\)为\(u,v\)的最近公共祖先,\(dis(u)\)表示树根到\(u\)的距离
每个节点可以是黑色或白色,初始结点颜色为白色
有\(m\)次操作,操作分为两种
将结点\(x\)染成黑色
记所有黑点形成的集合为\(S\)与一个节点\(x\),求出下面式子的值
\[ \sum_{y \in S}F(dis(LCA(u,v))) \]
其中函数\(F\)定义为
\[ F(x)=\sum_{i=1}^x i^k \]
解法
朴素的暴力是求取\(x\)与\(S\)中点的\(LCA\)并进行计算
我们考虑换一种角度,考虑\(LCA\)的贡献
\(x\)与\(S\)中点的\(LCA\)一定位于由\(x\)到树根的这一条路径上
对于每个修改操作,我们把由\(x\)到根的这条路径都打上标记(即加一)
每次查询就查询\(x\)到根上的路径的标记之和即可
为了保证复杂度,我们用树链剖分来处理
由于在修改时,我们将\(x\)到根的一整条路径上的标记都加了一,但对于点\(x\)来说,真正有意义的只是\(LCA(x,S_i)\)上的那一个标记,所以由根到\(fa[LCA(x,S_i)]\)上的标记实际上是不合法的
为了结局这个问题,我们可以把每个节点的权值设为\(F(dis(x))-F(dis(fa[x]))\)
这样求出来的和就只会计算到合法标记的贡献
为什么这样做是对的呢?这实际上是一个差分的操作
把差分数组的\([l,r]\)区间均加上\(1\),在求前缀和意义下实际上就是在\(a_l\)处加上了\(1\)
还要注意\(F\)函数要用线性筛进行预处理
代码
还没打,到时候再补