背景
以后好好学学树套树,高级数据结构,主席树,cdq,分治。
分治
分治在算法中处处有体现,只不过在联赛中不是在代码中显式地实现而已,然而这并不能动摇分治在更高级应用中的地位。在联赛中,归并排序,线段树都是分治的鲜活例子;在更高级的比赛中,非单调斜率优化中分治维护凸壳,cdq分治等也是常见的应用。
主定理(亟待更新)
算法分析的主定理提供了由分治法解决规模为 的问题的时间复杂度。设 为子问题数量, 为每个子问题的规模, 为解决子问题外额外的计算工作量,则有(Introduction to Algorithms):
我们可以给出封闭解,但这里只需记住当时有
。
CDQ分治
CDQ分治是基于时间的分治,此外还有基于值域的分治等。CDQ分治是一种离线算法,即获取所有修改和查询后统一回答。它能使编程、思维复杂度降低,如去掉一层树。通常实现为(当然不同题目实现不都相同):
solve(l, r)
{
1. solve(l, mid);
2. calc effects left to right;
3. solve(mid, r);
}
相比朴素做法,CDQ分治将左边修改的影响统一计算并应用到右边,很好地避免了时间浪费(gigo)。
线段树分治与线段树优化建图(亟待深入学习)
线段树的操作复习
普通线段树基于分治,能够解决许多问题。
权值线段树又称权值线段树,用例大大变换了视角
线段树合并与动态开点常常在树上操作(lyd)
(当然还有树状数组、分块、平衡树等你喜欢的各种数据结构)
(kma)线段树分治和线段树优化建图互通。通常我们会有这样的操作:对一个序列,反复对区间进行操作。我们以这个序列为下标,即序列中的每一个元素都是线段树的叶节点。这样可降低复杂度。一个常见的例子就是线段树优化建图(fsy)。
而考虑在时间点上每一个操作对询问的影响时,整道题对时间轴建立线段树。离线下来,每次操作对有影响的操作区间打上标记,这可以用可变长 vector 来降低空间开销。最后深度搜索扫一遍,利用可撤销数据结构来记录扫描的影响(回溯时撤销)。
一个奇妙的思想
主动考虑操作对接下来询问的影响。而非操作改变当前局面后询问来查询局面。
偏序做题指南(正在更新
题目会给出多个偏序条件,最后进行询问。
首先以任意一维排序,作为操作(查询和插入)数据结构的顺序来保证第一维。
然后使用数据结构,注意操作(查询和插入)下标和值,即可以管理两种数据。如序列这道题目就是树状数组偏序元作为下标,问题的答案元作为操作(查询和插入)的值。