ABC 337 G(主席树)

最近刚学完主席树,找了道题巩固一下,还是非常有收获的。

题目链接:problem

若只让求f(1),则还是比较简单的——用权值树状数组维护dfs路径上的数,每次查一下在 递归路径中>当前结点值 的结点数量,累加起来即为f(1)

可是题目要求将f(1)f(n)全部求出,且n<=2e5,显然不能对每个点都dfs一次来求,需要利用f(1)来计算出其他答案,这显然是换根DP的思路:

vu的儿子(整棵树以1为根),若f(u)已知,可以推出f(v),则问题解决。

pEFc5kQ.png

画出换根前后的两个图,可以发现:

f(3) = f(1) - 1对红色子树(包括3)的贡献 + 3对蓝色子树(包括1)的贡献

这里的贡献可以理解为逆序对的数量:

  1. 1红:对于红色子树内的所有点v,满足v<1v的数量
    1作为w)。此贡献在1下移后消失。
  2. 3蓝:对于蓝色子树内的所有点v,满足v<3v的数量
    3作为w)。此贡献在3上移后产生。而计算这个必须用
    v1<v的总数量)再减去红色子树中v<3v的数量得到(注意不能用蓝色子树,因为右图是换根后的想象图,而左图中的红色子树是真实存在的)。

因此,计算f(u),只需要知道在以u为根的子树中<某个定值k的数的数量即可。

可以发现,若将子树理解为子区间,则问题就转化为:查询给定区间的任意子区间中<k的值的数量。这个问题就是主席树的板子。

而子树恰好可以映射成子区间 -> 只需要处理出dfn序,这样一棵子树就恰好对应dfn数组中的一个连续的区间,所有子树就成为了dfn数组的子区间,对这个dfn序列建好主席树,对每个点用它的父节点递推计算答案即可,复杂度O(nlogn)

code

posted @   jxs123  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示
主题色彩