数据结构 - 基础数据结构
树状数组
单点修改,前后缀和。
实际上维护了 \((i-\operatorname{lowbit}(i),i]\) 的区间和。
为什么是对的,反着写为什么是对的。
性质:把 \(i\to i+\operatorname{lowbit}(i)\) 连边后是一棵树。
树状数组的快速清空
维护时间戳,表示最后一次修改的时间,常数更小。
线段树
抽象数据结构
什么是抽象数据结构。
对于线段树信息群 \(I\),标记群 \(D\),满足:
- 信息结合律:\(a,b,c\in I,(a+b)+c=a+(b+c)\)
- \(a\in I, b\in D,a+b\in I\)
- 标记可下传(标记可以集体下放更新到子节点的信息):\(a\in I,b,c\in D\),\((a+b)+c=a+(b+c)\)
- 标记满足结合律(标记可以和子节点的标记合并):\(a,b,c\in D,(a+b)+c=a+(b+c)\)
- 标记提前计算(在一点打上标记时,直接更新维护的信息):\(a,b\in I, c\in D\),\((a+b)+c=(a+c)+(b+c)\)
常数优化
让内存连续
- 对每个结点开 struct 存储信息
- 把 l,r 传入函数,利用栈空间缓存
规避不必要的递归和判断
- zkw 线段树(标记永久化)
标记永久化
直接在结点上永久更新标记。
标记额外满足交换律:\(a,b\in D, a+b=b+a\)。
动态开点
维护有效部分的虚树。
字典树 Trie
本质是长为 \(2^k\) 的值域线段树。支持合并。
线段树合并
弄清楚线段树合并和树上 dsu 的关系:线段树合并的优势在于维护的线段树 而不是合并。
复杂度使用势能分析,势能为线段树结点数。
线段树分裂
分裂为两个区间。
一次分裂最多花费 \(O(\log n)\) 的时间令势能增加 \(O(\log n)\),复杂度正确。
扫描线
矩形面积并
给出 \(n\) 个矩形,求并的面积。
维护 \(\sum_i[i=\min]\text{len}_i\)。
线段扫描线:P4605 [SDOI2018] 物理实验
平面上有一条无限长的导轨,有一个长为 \(L\) 的激光发射器,垂直于导轨向两边发光。有 \(n\) 块挡板,光不能透过挡板。求一个位置使得照亮的挡板长度之和最大。
扫描线,std::set 维护当前所有线段截距的大小相对关系,在端点加或删。
线段扫描线:CF704E Iron Man
有一棵 \(n\) 个点的树,\(m\) 个波特,第 \(i\) 个波特会在时间 \(t_i\) 出现在 \(u_i\),并以每秒 \(c_i\) 条边的速度向 \(v_i\) 匀速移动,到达点 \(u_i\) 时立即消失,两个波特在同一个位置会立刻爆炸。求出第一次爆炸的时间。
树剖。
线段扫描线:UOJ553 【UNR #4】己酸集合
线段扫描线:P6106 [Ynoi2010] Self Adjusting Top Tree
CDQ 分治
求解多维偏序问题,也可以优化 DP。
带修二维偏序可以转化为带时间戳的三维偏序通过 CDQ 求解。
P4690 镜中的昆虫
经典转化:颜色数维护 \(\operatorname{lst}\),转化为 \((i,\operatorname{lst})\) 的二维数点。
涉及修改:删旧加新,维护时间戳,转化为二维数点。
CF568E Longest Increasing Subsequence
列出式子,把 \(\max\) 转为一维条件 CDQ 优化 DP。
P5979 [PA2014] Druzyny
优化 DP。
树套树
加点、删点、矩形求和。在线。
对每个 \(x\) 维护 \(y\) 一维的动态开点线段树,树状数组或线段树维护 \(x\) 维度前缀线段树的并。
P3380 【模板】二逼平衡树
维护序列,\(m\) 次操作:查询 \(k\) 在区间内的排名;查询区间内排名为 \(k\) 的值;修改某一位的数值;查询 \(k\) 在区间内的严格前驱后继。
第一维是位置,第二维是值,树状数组维护动态开点权值线段树的并。
查询排名:在 \(\log\) 个线段树上查,\(\log^2\);查询第 \(k\) 大:二分,\(\log^3\)。
第一维是值,第二维是位置,线段树套线段树。
查询排名:在 \(\log\) 个线段树上查,\(\log^2\);查询第 \(k\) 大:线段树二分,\(\log^2\)。
线段树分治
或者叫 "猫树分治"、"二区间合并"。
参考资料
- 2023ZR 夏讲课及课件
- 2023ZR 国庆讲课及课件

浙公网安备 33010602011771号