题意分析
这是一道关于树上“崛起”的题目。我们先理解一下题意:
给定一棵nnn个节点的树,每个节点iii有aia_iai 次“access”“access”“access”操作。
每次崛起(access)(access)(access)城市iii时,国家iii会取得城市iii到城市1路径上所有城市的控制权。
灾难度 = 崛起过程中与不同国家进行战争的次数(同一国家多次只计一次)。
求所有可能崛起顺序中,灾难度之和的最大值。
方法:将问题转化为 LCTLCTLCT 模型:最大化accessaccessaccess操作中轻重链切换的总次数。
核心结论:
对于每个节点uuu,设其子树中所有aaa的值之和为SuS_uSu ,uuu的所有子树(包括uuu自己)中aaa的最大值为MuM_uMu 。
那么节点uuu对答案的最大贡献为:
min(Su−1,2∗(Su−Mu))min(S_u-1,2*(S_u - M_u))min(Su −1,2∗(Su −Mu ))
即:
当2∗Mu>Su+12*M_u > S_u+12∗Mu >Su +1时(某个子树或自己过大),贡献为:2∗(Su−Mu)2*(S_u-M_u)2∗(Su −Mu )。
否则,贡献为Su−1S_u-1Su −1。
修改操作的处理
当给axa_xax 加上www时,只可能影响xxx到根的路径上的点的贡献。
关键观察:如果某个子树的aaa之和大于其父节点子树aaa之和的一半,那么这条边是"重边",修改时贡献不变。
这启发我们用类似树链剖分的思想:
若某子树$sum \times 2 > 父节点总父节点总父节点总sum$,则为重边
每个点到根路径上轻边数量是O(log∑a)O(\log \sum a)O(log∑a)级别的
用LCTLCTLCT维护这些重链,每次修改时只需要处理轻边变成重边的情况。
代码:
关键思路总结
1.
问题转化:将"崛起"操作转化为LCTLCTLCT的accessaccessaccess操作,灾难度转化为轻重链切换次数
2.
独立贡献:每个节点的贡献可以独立计算,答案为各节点贡献之和
3.
贪心结论:对于每个节点,最大贡献为min(S−1,2(S−M))\min(S-1, 2(S-M))min(S−1,2(S−M))
4.
轻重链剖分:利用类似树剖的思想,重边修改时贡献不变,只需处理轻边
5.
LCTLCTLCT维护:用LCTLCTLCT维护重链结构,支持快速找到需要更新的轻边
点个赞呗