线段树深入——普适性の思路

更好阅读体验

Dans les mathématiques, le progrès vient souvent d'une abstraction plus profonde, plutôt que d'un calcul plus compliqué
— Alexandre Grothendieck

线段树深入——普适性の思路

0. 导引

前置知识:群的定义,环的定义 + 线段树(只用到动态开点?)

(不会的话,好的文章

其实这只是一总结性的文章;

其实现在精神状态十分美好

某些奇奇怪怪的东西会用 『』

无关紧要的定义会用引用

写在 『期末』 之前

1. 朴素线段树の本质

1.1 半群

在做了这么多的线段树的题之后,对于线段树能够维护的信息,我们都有了一个判断:

  1. 运算需要满足结合律。e.g. 定义在 \(\Z\) 上的加法 \(+\),有 \(\forall a,b,c \in \Z, a+b+c=a+(b+c)\)
  2. 封闭性。(这点应该很显然了)

很好

看到这个,你有没有想到一些东西 (如果没想到,先去补习群

没错就是『半群

__半群__

半群是一个二元组 \((G,\otimes)\)

  • \(G \not= \varnothing\)
  • \(\otimes\) 是定义在 \(G\) 上的运算 (封闭性)
  • \(\otimes\) 满足结合律,即 \(\forall a,b,c \in G, \ a\otimes b\otimes c=a\otimes(b\otimes c)\)

1.2 本质

所以说朴素线段树就是一个基于半群的数据结构,可以叫做『半群线段树』

半群线段树

半群线段树是一个数据结构,维护一个序列 \(\{a_n\}, a_i\in G,i=1,2,3...,n\)\((G,\otimes)\) 是一个半群

支持以下操作:

  • 修改,给定下标 \(\text{id},1\le\text{id}\le n\),修改值 \(d \in G\),使 \(a_\text{id}\larr d\)
  • 查询(区间查询),给定范围 \(\text l,\text r(1\le \text l \le \text r \le n)\),求 \(\otimes_{i=\text l}^{\text r}a_i\)

这样子,对于节点 id ,它的维护就是

\[\text{id} = \text{id}.\text{lson} \otimes \text{id}.\text{rson} \]

就是我们写的 pushup

注意

  • 对于初学者(抽象代数),应注意在半群上,运算没有交换律

  • 加上 lazy_tag 后,实质就并不是半群线段树了,可以说是『双半群结构』,也可以说是『环线段树

1.3 例题(或者说应用?)

区间求和、积

实数与加法、乘法肯定构成群

矩阵乘法

矩阵与矩阵乘法是构成群的

字符串 Hash

这玩意儿之前周考考过;

乍一看,这东西好像不满足结合律,可是再仔细看看呢

先看计算过程:

\[\boxed{\text{Hash} = (\sum_{i=0}^{\text{length-1}}\text{str}_i \cdot \text{base}^{n-i-1}) \ \text{mod}\ p} \]

不妨让 \(G\) 中的每一个元素为一个二元组 \((h,length)\)\(h\) 是字符串 Hash 值,\(length\) 是字符串长度

\(\to\) \(\otimes\) 的定义不就出来了吗

\[\forall s_1,s_2\in G, s_1 \otimes s_2=((s_1.h \cdot \text{base}^{s_2.length} + s_2.h)\ \text{mod}\ p, s_1.length+s_2.length ) \]

封闭性显然

  • $ (s_1.h \cdot \text{base}^{s_2.length} + s_2.h)\ \text{mod}\ p \ \in \ \Z_p$

  • \(s_1.length+s_2.length \ \in \ \N\)

结合律大家可以自己推推

1.4 信息设计~~

依然是从半群入手

本质上,就是一个『映射』(函数):\(f : ([1,n] \cap \mathbb Z)^2 \to G\)

哎呀,说简单点就是 \(f(x, y) \to G,x,y\in [1,n],\mathbb Z\)

参考

诶,我们又知道了:\(G \otimes G \to G\)。此时有了 \(f(l,\text{mid}) = x,f(\text{mid} +1, r) = y\) ,就有:\(f(l,r)=x \otimes y\)

具体的参考大佬博客

此时由于封闭性与结合律的限制,每个区间就唯一对应了一个值,且不会在维护时丢失信息

1.5 例题

不想写了

2. 环线段树,或者 双半群?

2.1 出来了

澄清一点,此环非彼环

其实这里的是抽象代数里的概念

__环__

:直接用大佬的定义了

环公理 ring axioms

(1) 集合 \(R\) 称为 ,若定义了满足以下公理的二元运算 \(+, \times\),称为加法和乘法:

(i) \((R, +)\)阿贝尔群

(ii) \(\times\) 满足 结合律

(iii) \(R\) 满足 分配律:对任意 \(a, b, c\in R\)\((a + b) \times c = a \times c + b \times c\)

(2) 若乘法交换,则 \(R\) 称为 交换环 commutative ring

(3) 若存在 \(1\in R\) 满足对任意 \(a\in R\)\(1\times a = a\times 1 = a\),则称 \(1\)单位元

乘法符号一般省略。加法群的单位元记为 \(0\),逆元记为 \(-a\)

其实吧,也可以说成是 双半群 结构(信息一个半群,lazy_tag 一个半群)

环线段树是一个数据结构,维护序列 \(\{a_n\},a_i\in R,i=1,2,3...,n\),支持操作:

  • 修改(区间),给定范围 \(\text l, \text r\),以及修改值 \(d\),使 \(\forall i \in[\text l,\text r],a_i \larr d \times a_i\)

  • 查询(区间),给定范围 \(\text l, \text r\),求 \(\sum_{i=\text l}^{\text r}a_i\)

    这,就是一个带 lazy_tag 的线段树

2.1 油水分离,如何将值与标记分开

注意:一般题目中有多少个修改操作,就有多少个 tag

规定

  • 将值记为 val

  • 将标记记为 tag

  • 将值的集合记为 \(D\)

  • 将标记集合记为 \(T\)

    有以下运算需得到满足:

  • \(\times : T \oplus D \to D\),给某个值加上标记

  • \(\times : T \oplus T\to T\) ,标记的下传, \(\iff\) pushdown

  • \(+:D\oplus D \to D\),值的求和

    然后呢,我们发现 \(D\) 总是多维向量的集合,\(T\) 总是方阵的集合(大小:若 \(D\)\(n\) 向量集合,则每个方阵大小为 \(n\times n\)

2.3 依旧应用

区间加乘+区间求和

加与乘都是线性变换,就维护向量 \([a_i,1]\),修改就乘上一个 \(2\) 阶方阵

·······(实力有限,憋不出来了)

2.4 忘了

有一篇比较好的讲区间历史操作,从矩阵乘法到标记的文章

3. 特殊的线段树

先鸽着,因为我不会

4.后记

抽象化不是为了变难,而是为了变得更加简便,方便与实践。

这是我想对我们班同学说的

在学到线段树的时候,我就开始疑惑,线段树的本质是什么

再找了几篇博客后,已经有了些初步理解

也写了篇纸质版总结

我个人认为在彻底理解到这『普适性の思路』后,解决这类题的思路就有了一个固定、可靠的『路径(Path)』,虽然我还很弱

参考资料:

抽象线段树理论

区间历史操作,从矩阵乘法到标记

《抽象代数》学习笔记 I —— 群论 - qAlex_Weiq - 博客园

《抽象代数》学习笔记 II —— 环论 - qAlex_Weiq - 博客园

线段树进阶 Part 1 - qAlex_Weiq - 博客园

"Wir müssen wissen, wir werden wissen."

——大卫・希尔伯特

posted @ 2026-01-16 20:12  Yangyihao  阅读(3)  评论(0)    收藏  举报