zoukankan      html  css  js  c++  java
  • 树上差分的两种实现形式

    简单理解树上差分(点,边)

    关于树上差分,我在这推荐一道题目POJ 3417 。

    题目翻译:https://loj.ac/problem/10131。

    树上差分用来解决点的覆盖或者边的覆盖的问题,需分别运用点的差分或者边的差分。

    先从例题入手:

    给定点数为N,边数为N-1的树(无向边且无重边),先有M条连接a,b的非树边,求每条“树边”被“非树边”覆盖了多少次?

    边的差分:

    先设一个F【x】,是一个差分数组,表示从X到X的父亲的边被覆盖的次数。对于每一次输入的a , b,朴素算法是O(n)的去遍历每一条边,这样的时间复杂度太高了,我们就可以用差分的思想去优化,就是树上差分,即F[a]++,F[b]++,F[lca(a,b)]-=2;

    从X到X的父亲的边被覆盖的次数就是X的子树和了,前缀和的思想。

    但是我无法证明这种方法,如果有神犇能证明,麻烦下方评论告知,O(∩_∩)O谢谢。

    再来一道例题:

    给定点数为N,边数为N-1的树(无向边且无重边),先有M条连接a,b的非树边,求每个“点”被“非树边”覆盖了多少次?

    不难看出,这道题只是把“树边”改成了“点”。

    点的差分:

    设F【x】为x被覆盖的次数。修改F【X】的时候也要变化,还是输入a,b。修改的操作为F[a]++,F[b]++,F[lca(a,b)]--,F[father[lca(a,b)][0]]--;最后一个是LCA(a,b)的父亲。同样,X的子树和就是X点被覆盖的次数。求每个点的子树和只需要DFS一次,复杂度是O(NlogN)的。

    实在不理解可以举2个例子模拟一下:

    1.从a到b。a,b均不是LCA(a,b)。

    2.从a到b。a,b其中之一为LCA(a,b)。

    总结一下:树上差分用来解决“点的覆盖”或者“边的覆盖”的问题,是朴素的直接遍历算法的优化,将朴素算法覆盖的时间复杂度O(N*M),直接优化为O(N),时间复杂度十分优秀。

  • 相关阅读:
    Execl获取真实行数
    日期工具类
    Eclipse & IDEA快捷键对比大全
    【转】IDEA导入Eclipse项目 详细步骤(亲自验证导入成功)
    京东的四大集团
    马云演讲视频
    阿里系的一些重要网站
    阿里系的几个电商网站
    腾讯几款QQ软件
    电脑版微信使用说明
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9498276.html
Copyright © 2011-2022 走看看