数据结构结合了多种思想,较为复杂。
单调栈
单调栈可以O(n)求出第一个>=x的值及其位置,也可以建立笛卡尔树。
这个特点使得单调栈可以完成维护多维信息的一些形同整体<=某个值的限制。
笛卡尔树
单调栈的进阶运用,其子树组成的集合可以自然构成一段符合整体<=某个值的区间,在随机数据下,深度为$O(logn)$。
单调队列
单调队列及时排除了不优数据优化复杂度。结合函数知识,即成为了斜率优化。
分治
分而治之,如果小区间的影响可以高效扩大到大区间上,能显著降低复杂度。
对于一些特殊的问题,需要从两边扫,降低复杂度。
如果是将询问离线,整体二分(实际上是分治),可以将一类询问一起处理,高效求出区间第k小问题,它会将操作按照区间划分,所以也是一种单调性思想。
CDQ分治,也是常用的思想,比起整体二分,CDQ分治更关注一个区间对另一个区间的影响,可以解决偏序问题和区间排名问题。动态问题也可以被转化为CDQ分治。
并查集
基础功能是维护联通性,但也可以维护一些二元关系。
倍增
加速一些枚举过程,也可以维护最值及其位置
ST表
O(1)查询利器
线段树
维护具有传递性的信息,有时可以将一部分信息拆完位维护。
线段树矩阵是维护信息和懒标记的利器。
还有线段树分治做法。略过。
树链剖分
拍平,线段树维护。
李超线段树
维护函数的线段树,结合势能法。
平衡树
维护排名同时还能维护其它信息,支持懒标记,可持久化。
莫队/分块
维护难以用常见数据结构维护的信息。
堆
用于最短路算法较多
简化问题
尽量维护更少,更精简的信息来计算。写题前可以做形如将内容分为不同类等操作或用不同数据结构维护。
进阶篇(套路集合)
写出操作的线性变换形式,就可以直接套用矩阵
扫描线可以减少一部分问题变量。
bitset可以极大优化部分问题复杂度
难点
问题转化
确定维护对象
转移