【未完工题解】P3345 [ZJOI2015] 幻想乡战略游戏
【P3345】题解
一:【题目描述】
- 给定一个带点权和边权的树
- 每次修改一个点的点权
- 定义F[u]:dis(u,i)*nw[i]
- 求F[u]最小值
二:【求解】
1.【暴力解法】
定义d[u]为u子树内点权和
钦定root暂时最优解,每次枚举其子节点v,每次变化量为(d[u]-2d[v])dis(u,v)
接下来证明如果d[u]-2d[v]<0,则带权重心一定在v子树中
我们考虑反证,如果d[u]-2d[v]>0,则带权重心一定不在v子树中
引入v子树中节点w,满足d[w]<d[v]
因为d[u]>2d[v],则d[u]>2d[w],所以一定不在v子树中
那么如果d[u]-2*d[v]<0,则带权重心一定在v子树中
所以我们一直递归,直到所有v满足d[u]-2*d[v]>0,此时u为带权重心
但是如果树退化成一条链,则单次询问复杂度为O(n),显然TLE
2.【点分树解法】
考虑查询操作
如果树高度是logn的话,那么单次询问复杂度就是O(logn)的,可以通过此题
我们重构成点分树,在点分树上采取暴力解法
具体来说,钦定点分树root为最优解,每次枚举其在原树上的邻接点v,如果d[u]-2*d[v]<0,则跳到v所在的连通块的重心t上,这样可以保证复杂度正确(类似二分)
然后用类似换根的思路,修改t->u方向上t的邻接点w的d[w],离开的时候再复原
最后得到带权重心r,然后按照点分树容斥的套路f-g计算答案即可
修改操作的话,向上跳,修改祖宗节点的f,g就可以了
复杂度O(20qlog^2n)
不过对于查找重心,还有一种更简单但是常熟略大的思路,可以避免复杂的换根操作
钦定root为最优解,每次枚举其在原树上的邻接点v,直接点分树上查询计算F[v],在所有子节点的F[v]中取最小值,如果F[v]<F[w],跳到v所在连通块的重心
递归下去,就可以找到带权重心
复杂度O(20qlog^2n)
三:【代码】
(施工中...)

浙公网安备 33010602011771号