Re: 从 0 开始的 DS 学习笔记
Last Update:
WARNING: 本文包含以下内容:
人外 (DS 确实不是人)
强暴 (某些确实挺暴力的)
高中生 (我自己就是)
基础内容#
实在太基础了拎出来单丢一节了
单调栈, 单调队列#
单次操作复杂度
多用于某些问题的优化, 这类问题多类似贪心, 可以排除一些无用解.
Hash#
多用于
字符串的最强算法 : SAM
字符串的 Hash 可以简单的差分.
同样可以支持对树做
并查集#
维护集合的常用数据结构, 无法维护时考虑 LCT.
船新科技: 支持删除#
具体方法: 删除的时候新建一个空节点替代将被删除的节点即可. (惰性删除)
路径压缩的适用范围#
路径信息不重要的题目, 或者在压缩时可以快速并且不破坏的维护路径上的信息.
启发式合并与按秩合并#
启发式合并: 考察即将合并的两个集合的大小, 永远将小的集合合并到大的上 (如果能在
按秩合并: 仅在并查集上能完成
堆#
支持插入删除的维护最大值. 某些支持一些额外操作.
左偏树 (可并堆)#
定义某个节点的
考虑解决两个左偏树的合并:
1 |
|
考虑使用此操作支持其他操作:
int newHeap(int val)
: 直接支持即可,
void insert(int x, int val)
: merge(x, newHeap(val));
即可,
void del(int x)
: merge(tr[x][0], tr[x][1])
后从下向上考虑, 每当
对堆中的所有对象全体操作类: 凡是不改变相对大小(加减乘正数), 或者做
「SCOI2011」棘手的操作#
题面#
有
U x y
加一条边, 连接第个节点和第 个节点. A1 x v
将第个节点的权值增加 . A2 x v
将第个节点所在的连通块的所有节点的权值都增加 . A3 v
将所有节点的权值都增加F1 x
输出第个节点当前的权值。 F2 x
输出第个节点所在的连通块中, 权值最大的节点的权值. F3
输出所有节点中, 权值最大的节点的权值.
解法#
考虑到操作 F2
, 显然应该使用可并堆.
考虑到除了 A2
操作, 其他操作都是基本可并堆操作. 这里只讨论 A2
操作. 不妨考虑对于每个堆, 在堆顶维护一个
ODT#
维护序列信息, 基于随机性. 要求操作中有区间推平.
具体来讲, 维护一个区间的集合. 在一个区间被推平时, 我们将其所有位置拆出来, 然后新建一个新区间维护这些位置的信息.
采用 std::set
维护这些区间.
进阶 (?) 内容#
树状数组#
单点修改, 前缀和.
对于任意一个序列
常用 trick : 倍增砍老哥 (
线段树#
万恶之源.
区间修改, 区间求和.
对于