《浅谈一类基于线段树分治的信息维护算法》学习笔记
自己复习用,写的很随性,所以可能看不懂。
经典算法
维护一张 \(n\) 个点的简单无向图,有 \(m\) 次操作,支持加边删边,询问两点间连通性。
非常经典的线段树分治题,不再赘述。
算法1
有一张 \(n\) 个点 \(m\) 条边的无向图,第 \(i\) 个点只在第 \(L_i\) 到 \(R_i\) 这段时间出现。你需要对于每个点 \(i\),判断是否存在一个时刻 \(x\) ,使得 \(i\) 和 \(1\) 联通。
\(n\leq 2\times 10^5,m\leq 4\times 10^5\)
\(1\leq L_i\leq R_i\leq 2\times 10^5\)
考虑转化为,给每个时刻与 \(1\) 联通的连通块的点权 \(+1\)。
给并查集的根打上 lazytag,撤销时给 tag 差分一下即可。
算法2
上面的题目要求信息有逆元,我们考虑如下加强:
连通块对 \(v\) 取 max,求连通块最大值。
考虑写出一个类似 Kruskal 重构树的东西,即每次合并新加一个节点,撤销删除并下放 tag 即可。
精细实现可以做到线性空间。
应用
不难发现对于序列问题可以直接使用如上算法,可以做到 \(O(n+(m\log q+q)\log n)\)。
又发现我们来自并查集的 \(\log\) 实际上可以 \(O(1)\) 维护,所以可以做到单 \(\log\)。
算法3
单点修改权值,单点查询权值。
我们考虑用二进制分组 \(+\) 线段树来维护(点信息表示前缀和)。
不难发现,此时所有操作均可 \(O(\log)\) 维护。
合并两个集合相当于单点插入一个数。
分裂两个集合相当于单点查、删末尾、下传 tag。
整体修改为给所有线段树打全局 tag。
单点修改需要对目标点到根节点上的所有 \(\log\) 个点的下传标记,修改,然后合并。
总复杂度 \(O(n+m\log q\log n+q\log^2 n)\)。
可持久化
待学习。

浙公网安备 33010602011771号