• cojs 简单的最近公共祖先 解题报告


    我曾经自己想过每考试一次就从考试题中找找idea来出题

    这次又找到了一个,先不管原来的考试题是什么

    考试题中其中的一部分就是今天的这道题目啦

    当时考场上自己比较傻,没有注意到有用的性质,套用了之前黑白树系列的做法

    写的是log^2n的,结果导致只能在开O2的情况下A掉这道题目

    后来仔细研究了以下,得到了本题的做法

    首先我们观察操作中和黑白树系列的那道题目的区别

    1、只有染黑操作,没有染白操作

    2、不需要可持久化,不需要满足可减性

    之后观察题目的性质:

    1、转化成暴力写法,每次修改u到根的路径,查询u到根的路径

    我们知道修改和查询路径我们可以利用树链剖分+线段树在log^2n的时间内完成

    但是仔细考虑性质我们会发现每次修改和查询的一个端点都是根

    对于一条链而言,我们每次修改只会修改这条链的顶端top到某个点的值

    而又因为只有染黑操作,我们一旦把这条链的顶端top到某个点都染黑之后,这段不可能在被染白回去

    那么很明显我们不需要用线段树,可以机智的去掉线段树的那个log

    具体做法如下:

    我们树链剖分,对于每条链维护一个点u并记录顶端top

    每次更新的时候只需要观察更新点的深度是否大于u即可

    每次更新是O(1)的,每次最多修改logn条链,修改操作时间复杂度logn

    对于查询,我们从u节点向上跳链,如果当前链被修改过,证明答案一定在这条链上

    之后我们考虑这条链记录的值u‘的深度,如果大于当前跳到的点u,则答案就是u

    否则就是u’

    我们每次最多跳logn条链,所以查询时间复杂度logn

    至于C操作,时间戳就O(1)啦

    总时间复杂度mlogn,常数非常小

    在我把考试题的这部分改成这个写法之后就可以在不开O2的情况下A了,而且用时大概是时限的一半

    下面说一下有关于出这道题目的一些心得:

    1、这个题目的做法我不确定是最优的,可能会有并查集或者O(n)的做法之类的(不过估计需要离线)

    如果有更优的做法欢迎与我讨论

    2、有关于卡住log^2n:

    首先这道题之前的做法是倍增+树状数组,由于维护子树和可以支持染白和可持久化

    我一开始调整了树的深度和修改的次数(因为修改是log的,只有查询是log^2的)

    使得这个做法会T掉几个点,但是后来我发现由于倍增数组,内存并不兹磁这个做法QAQ

    还有一种更显然的做法是树链剖分+线段树,这样修改和查询都是log^2的

    这个做法我没有刻意去卡,因为不卡他也会T掉

    还有一种做法是上面的优化,就是整条链的修改直接在链上打标记,不维护全局线段树,对于每个链单独开线段树

    这样常数会小很多,每次查询的时候只需要跳到第一个有修改标记得链,在线段树上二分就可以了

    查询就是log的了,修改还是log^2的

    我写了一发,不是很难写,可以过9个点,常数写的比我漂亮一点貌似就能A了

  • 相关阅读:
    最富有客户的资产总量
    无重叠区间
    工作流分析推荐
    sharepoint外包和定制开发公司分析比较及推荐
    sharepoint开发企业信息门户系统分析及公司推荐
    北京sharepoint开发公司比较推荐
    国内市场主流专业的sharepoint开发公司分析比较及推荐
    北京工作流软件公司分析比较和推荐
    国内市场主流专业的工作流(bpm)软件分析、比较及推荐
    Hibernate的多对多实例
  • 原文地址:https://www.cnblogs.com/joyouth/p/5487096.html
Copyright © 2020-2023  润新知