9.13 染上你的颜色

题意

给定一颗有根带权树,记\(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\)函数要用线性筛进行预处理


代码

还没打,到时候再补

猜你喜欢

转载自www.cnblogs.com/VeniVidiVici/p/11519956.html