• 【考试总结】20220804


    大家

    令一个没有被点亮的点为根,设 \(f_{x,0/1/2,0/1}\) 表示 \(x\) 为根的子树里面有路径的 \(0/1/2\) 个端点,此时得到的不完成的序列使得 \(x\) 的开灭状态为 \(0/1\) 的最小序列长度

    值得指出的是,\(f_{x,2,* }\) 的常规理解是 \(x\) 子树中的序列在最终序列中分成两截,\(x\) 在第一截末和第二截初出现。但是出于最终统计答案的方便,这两次出现只记录一次。\(f_{x,0/1, * }\) 不受影响,\(x\) 在子段末尾的出现不作修补。

    合并那些存在没被点亮的点的子树,设当前要合并 \((u,v)\)。路径端点数量的这一维度是背包。

    如果 \(v\) 中不设置端点,直接压到序列末尾即可。此时在子树遍历序列尾添加一个 \(u\) 连接 \(u\) 和之后的序列。如果 \(v\) 没有被点亮就向下走一步去点亮。

    如果 \(v\) 中设 \(1\) 个端点,如果是从 \(f_{x,0,*}\) 转移到 \(f_{x,1,*}\) ,由于之前归并的部分前后都有 \(x\) ,于是两段长度相加即可;如果从 \(f_{x,1,*}\) 转移到 \(f_{x,2,*}\)\(f_{x,1,* }\) 作为前半段,它的末尾有 \(x\)\(f_{v,1,* }\) 作为后半段,它的开头没有 \(x\),恰可以满足 \(f_{x,2,* }\) 的定义。于是不需要额外讨论或者长度附加。这里没点亮还会让序列长度加 \(2\)

    如果 \(v\) 中有两个端点,于是之前 \(u\) 子树中不能存在端点,最终序列可以表示成将 \(u\) 已经得到的序列嵌进 \(v\) 得到的序列,由于 \(u\) 向上的部分不添加,于是 \(u\) 的状态不变。如果 \(v\) 再添加返祖位后没有被点亮,需要往返一次将其点亮,此时 \(u\) 的状态也发生了改变。

    时间复杂度 \(\Theta(n)\)

    \(dp_{x,1,* }\) 的转移真的很神奇,怎么看怎么神奇

    身体

    分治,考虑 \(a\) 的最小值在左侧时,在右侧的情况可以翻转序列处理。以下提到的 \(a,b\) 都表示分治中点到 \(i\)\(a/b\) 最小值

    枚举 \(i\in[l,mid]\) 。那么当 \(b\) 的最小值也在左区间时,能满足条件的最大右端点可以双指针得到。

    否则 \(b\) 的最小值在右区间,上面提到的双指针也可以确定满足这一条件的合法区间(\(a_i\)\(\min a\))。而此时贡献形式为 \(a_ib_j(j-i+1)\) ,每个 \(i\) 的最优决策点可以用凸包来得到。

    又由于有合法区间的限制,需要线段树维护凸包。

    时间复杂度 \(\Theta(n\log^2n)\)

    健康

    \(x,y\) 没有祖孙关系时,它们的 \(\rm LCA\) 只能是给定的关键点之一。如果可以实现将给定关键点建带有包含关系的树之后可以直接求 \(\Theta(n)\) 个点的 \(\rm LCA\)。询问是将 \(x,y\) 定位到所在直链的下端点再处理即可

    求树时初始化 \(n+1\) 个直链的底标号为最后一层点,一层点变成上一层时需要删掉一个,右边的点左移一位。使用权值线段树来模拟整个过程,删点就是权值赋 \(0\),求某个 \(a_i\) 所控制的两条直链的链底可以线段树上二分。之后再将 \(a_i\) 对位的链底标号修改即可

    由于查询的时候还是需要每一层的信息,那么需要将线段树可持久化

    时间复杂度 \(\Theta(n\log n)\)

  • 相关阅读:
    shell脚本day06-sed
    shell脚本day05-交互式输入与for语句
    shell脚本day04-if语句
    shell脚本day04-grep与正则表达式
    shell脚本day03-编程原理
    shell脚本day02-重定向与管道符
    编程原理大致介绍
    进程管理
    Linux网络
    shell脚本--grep以及正则表达式
  • 原文地址:https://www.cnblogs.com/yspm/p/TestReview20220804.html
Copyright © 2020-2023  润新知