因为身体不舒服所以来写 GDOI 的防 AK 题了(?
首先把 1 抽出来当根。
记 fak(u) 表示 u 的 k 级祖先。
记 dep(u) 表示 u 到根的距离。
记 fi(u) 表示 u 子树内的黑点与 u 的距离的 i 次方和(i∈{0,1,2})。
对于一次询问,设 w=LCA(u,v)。
分类讨论所有黑点与 Path(u,v) 最近的点为哪个点。
若其在 w 子树外,则意味着在 w 处取到距离的最小值。
考虑 fak(w) 的贡献,则其为 f2(fak(w))−(f2(fak−1(w))+2f1(fak−1(w))+f0(fak−1(w)))+2k(f1(fak(w))−f1(fak−1(w))−f0(fak−1(w)))+k2(f0(fak(w))−f0(fak−1(w)))
讲人话就是在 fak(w) 子树内但不在 fak−1(w) 子树内的黑点的贡献。
对于 k=1…dep(w) 对上式求和可得 f2(1)+2dep(w)f1(1)+dep2(w)f0(1)−f2(w)−4dep(w)−1∑k=0(f1(fak(w))+(k+1)f0(fak(w)))
若其为 Path(u,w) 上的点,设 s=depu−depw,则考虑 fak(u) 的贡献: f2(fak(u))−(f2(fak−1(u))+2f1(fak−1(u))+f0(fak−1(u)))
对于 k=0…dep(u)−dep(w)−1 对上式求和得 −dep(u)−dep(w)−1∑k=0(2f1(fak(u))+f0(fak(u)))
同理可得 Path(v,w) 上的贡献,再加上在 w 子树内但不在 u,v 子树内的贡献,综合可得 f2(1)+2dep(w)f1(1)+dep2(w)f0(1)−4d∑k=0(f1(fak(w))+(k+1)f0(fak(w)))−s∑k=0(2f1(fak(u))+f0(fak(u)))−t∑k=0(2f1(fak(v))+f0(fak(v)))
其中 d=dep(w)−1,s=dep(u)−dep(w)−1,t=dep(v)−dep(w)−1。
到这一步其实已经可以维护了,但是由于我比较懒,所以考虑搞出一个更好维护的形式。
记 gi(u) 表示 u 子树内黑点 dep 值的 i 次方和。
则显然 f0(u)=g0(u),f1(u)=g1(u)−dep(u)g0(u)
代入原式再一顿乱化可得 f2(1)+2dep(w)f1(1)+dep2(w)f0(1)−4d∑k=0g1(fak(w))−4(dep(w)+1)d∑k=0g0(fak(w))+8d∑k=0dep(fak(w))g0(fak(w))−2s∑k=0g1(fak(u))+2s∑k=0dep(fak(u))g0(fak(u))−s∑k=0g0(fak(u))−2t∑k=0g1(fak(v))+2t∑k=0dep(fak(v))g0(fak(v))−t∑k=0g0(fak(v))
那么需要支持维护 g0(u),dep(u)g0(u),g1(u),比较简单。
JZOJ 卡栈传统艺能。
代码:
1 |
|