可持久化线段树 (Persistent Segment Tree)
1. 核心思想:共享结构 (Shared Structure)
- 基本原理:每次修改操作不复制整个结构,而仅创建\(O(\log n)\)个新节点。
- 关键技术:动态开点。
- 每个节点显式存储左右儿子的索引。
- 分配新索引时,不同版本的根节点(root)指向不同的子结构。
2. 数据结构定义 (Data Structure Definition)
/* by yours.tools - online tools website : yours.tools/zh/blood.html */ // 节点结构:包含左儿子、右儿子索引及维护的值 type Node: { le, ri, val } // 可持久化线段树主体 type Pers. SegTree: nodes[], // 存储所有节点的池子 roots[], // 存储不同版本的根节点索引 n // 维护序列的总长度 // 创建新节点函数 function newnode(l=0, r=0, v=0): nodes.append(Node(l, r, v)) return nodes.size() - 13. 可持久化更新操作 (Persistent Update)
核心逻辑:复制路径上的节点(此处以单点更新为例)。
/* by yours.tools - online tools website : yours.tools/zh/blood.html */ // 复制节点:从旧节点克隆信息到新节点 function copynode(old): nodes.append(nodes[old]) return nodes.size() - 1 /** * 更新操作 * @param prev : 上一版本的对应节点索引 * @param l, r : 当前区间范围 * @param pos : 待修改的位置 * @param val : 修改后的值 */ function update(prev, l, r, pos, val): cur = copynode(prev) // 复制当前节点,实现可持久化 if l == r: nodes[cur].val = val // 到达叶节点 (注:原笔记此处为.sum,语义等同) return cur mid = (l + r) >> 1 if pos <= mid: // 递归更新左子树,并将新生成的节点索引连在当前节点的左儿子上 nodes[cur].le = update(nodes[cur].le, l, mid, pos, val) else: // 递归更新右子树 nodes[cur].ri = update(nodes[cur].ri, mid + 1, r, pos, val) pushup(cur) // 向上更新当前节点的信息 return cur4. 经典应用:区间第\(k\)小 (Static Range K-th Smallest)
- 问题描述:给定长度为\(n\)的数组,进行\(q\)次查询,每次查询区间\([l, r]\)中第\(k\)小的元素。
- 技术要点:
- 值域建树:针对数值范围(或离散化后的秩)建立线段树。
- 版本前缀和:依次从\(1 \sim n\)插入元素,建立\(n\)个版本。第\(i\)个版本存储了前\(i\)个元素的分布情况。
- 区间转化:利用前缀和思想,查询\([l, r]\)等价于在“第\(r\)个版本”与“第\(l-1\)个版本”的差异结构上进行二分查找。
5. 带修改的区间第\(k\)小 (Dynamic Range K-th Smallest)
- 局限性:标准主席树是前缀和结构(线性的),单点修改会导致后续所有版本失效。
- 解决方案:
- 结合BIT (树状数组)的二进制结构进行分解。
- 用 BIT 维护一束线段树(树套树)。
- 操作:修改操作变为修改 BIT 中的\(\log n\)棵树;查询时在\(2\log n\)个对应的版本节点上同步二分。
- 复杂度:时间复杂度\(O(n \log^2 n)\)。
6. 可持久化并查集 (Persistent DSU)
- 实现方式:利用主席树实现可持久化数组,以此维护并查集的
fa(父亲)和rank(按秩合并高度)。 - 操作逻辑:
- 每次
find和unite操作基于某个版本进行。 - 必须使用按秩合并,避免使用路径压缩(路径压缩会破坏版本结构且导致大量节点新建)。
- 每次
- 复杂度:\(O(\log^2 n)\)(主席树访问\(\log n \times\)并查集深度\(\log n\))。
- 注意:底层基本操作返回新节点索引,高层逻辑函数返回新版本的根节点编号。
7. ⚠️ 警告与经验总结
- 空间预分配:可持久化线段树空间开销巨大,通常需要开到\(40n\)或\(25(n+q)\)左右。
- 修改原则:每次修改必须先复制原节点,在副本上进行修改,严禁直接改动历史版本的数据!
8. 经典例题解析
例题 23.3 (CF 893F)
- 题目:给定一棵\(n\)个点的有根树,点有权值。\(q\)次查询点\(u\)的子树中,深度不超过\(dep(u)+k\)的节点中的最小权值。
- 解法:
- 求出树的DFS 序,子树在序中对应一个连续区间。
- 在 DFS 序上建立以深度 (dep)为索引的主席树。
- 查询时在对应的子树区间版本内,进行深度范围内的前缀最小值查询。
例题 23.5 (CF 840D)
- 题目:给定长度\(n\)的数组\(a\),\(q\)次查询\([l, r]\)中出现次数严格大于\(\frac{r-l+1}{k}\)的最小元素。
- 核心逻辑:鸽巢原理。出现次数超过\(\frac{len}{k}\)的数,最多只有\(k-1\)个(当\(k=5\)时,最多 4 个)。
- 方案 I:主席树 + 二分
- 在线段树上查找时,只进入那些“节点计数值\(> \frac{len}{k}\)”的子树。
- 方案 II:随机化
- 在\([l, r]\)随机抽样\(M\)次,总成功概率为\(1 - (\frac{k-1}{k})^M\)。
- 技巧补充:
- 先离散化。
- 利用
std::vector记录每个数值出现的所有索引。 - 通过两次
std::upper_bound相减,可在\(O(\log n)\)内\(O(1)\)检查某个数在\([l, r]\)的实际出现次数。
补充 (Lecturer's Supplements)
- 关于动态第\(k\)小:在使用 BIT 维护主席树时,空间压力极大。如果题目允许离线,CDQ 分治通常是空间更优的替代方案。
- 关于按秩合并:在可持久化并查集中,如果不按秩合并而只用路径压缩,单次操作的最坏复杂度会退化,且新建节点过多会导致 MLE(内存超限)。
- CF 840D 的阈值:该题中\(k\)的范围通常很小(如\(k=5\)),这使得我们可以在线段树上同时递归多条分支而不会影响\(O(\log n)\)的查询量级。
第一档习题集
N1. 模 12 加法群的子群
- 已知:\(G = \mathbb{Z}_{12}\),\(H = \langle 4 \rangle = \{0, 4, 8\}\)。
- \(H\)的全部左陪集:
- \(0 + H = \{0, 4, 8\}\)
- \(1 + H = \{1, 5, 9\}\)
- \(2 + H = \{2, 6, 10\}\)
- \(3 + H = \{3, 7, 11\}\)
- 指数:\([G : H] = 4\)。
- 拉格朗日定理验证:\(|G| = [G : H] \cdot |H|\),即\(12 = 4 \times 3\)。
- 完全代表系(Transversal):\(\{0, 1, 2, 3\}\)。
N2. 模 15 乘法群的子群
- 已知:\(G = \mathbb{Z}_{15}^* = \{1, 2, 4, 7, 8, 11, 13, 14\}\)(注:与 15 互素的元素)。
- 子群:\(H = \langle 4 \rangle\)。
- \(4^1 \equiv 4\),\(4^2 \equiv 16 \equiv 1 \pmod{15}\),故\(|H| = 2\)。
- \(H = \{4, 1\}\)。
- 指数:\([G : H] = 8 / 2 = 4\)。
- 所有陪集:
- \(1 \cdot \{4, 1\} = \{4, 1\}\)
- \(2 \cdot \{4, 1\} = \{8, 2\}\)
- \(7 \cdot \{4, 1\} = \{13, 7\}\)
- \(11 \cdot \{4, 1\} = \{14, 11\}\)
N3. 对称群\(S_3\)的陪集(非正规子群示例)
- 已知:\(G = S_3\),\(H = \{e, (12)\}\)。
- 首先\(H \leq G\)且\(\langle (12) \rangle = H\),故\(H < G\)。
- 计算左陪集(\([G:H]=3\)):
- \(e H = \{e, (12)\}\)
- \((13) H = \{(13), (13)(12)=(123)\}\)
- \((23) H = \{(23), (23)(12)=(132)\}\)
- 计算右陪集:
- \(H e = \{e, (12)\}\)
- \(H (13) = \{(13), (12)(13)=(132)\}\)
- \(H (23) = \{(23), (12)(23)=(123)\}\)
- 结论:左右陪集显然不同(如\((13)H \neq H(13)\)),因为\((13)(12)=(123)\)而\((12)(13)=(132)\)。
N4. 循环群的子群链
- 已知:\(G = \mathbb{Z}_{24}\),\(H = \langle 6 \rangle\),\(K = \langle 12 \rangle\)。
- 包含关系:显然\(H, K \leq G\)。
- 且由于\(6 \mid 12 \Rightarrow \langle 12 \rangle \leq \langle 6 \rangle\)。
- \(H = \{ \langle 12 \rangle, 6 + \langle 12 \rangle \} = \{0, 6, 12, 18\}\)。
- 结论:\(K \leq H \leq G\)。
- \(G = \{H, 1+H, \dots, 5+H\}\)。
- 指数计算:\([G:H]=6, [H:K]=2, [G:K]=12\)。
N7. 组合数学/算法 (CF 1422C)
题目:给一个正整数(以字符串形式),可删其中一个连续子串,求所有可能剩余数之和\(\pmod P\)。
- 核心策略:按位计算贡献。
- 位置\(i\)处数字\(a_i\)的贡献(设\(i\)为从前往后第\(i\)位,下标从 1 开始):
- \(a_i\)在被删子串左侧:其位权保持不变。
- \(a_i\)在被删子串右侧:其位权因右侧位被删而发生位移。
- 贡献公式:
对于第\(i\)位的数字\(a_i\):\[\text{Contribution} = \left( \sum_{dlen=1}^{i-1} (i - dlen) 10^{i-1-dlen} \right) \times a_i + 10^{i-1} \times \frac{(n-i)(n-i+1)}{2} \times a_i \]记左侧贡献累加项为\(F_i\):\[F_i = \sum_{d=1}^{i-1} (i-d) 10^{i-1-d} = 10 F_{i-1} + \frac{10^{i-1}-1}{9} \](注:原笔记末尾推导公式为\(F_i = 10 F_{i-1} + \frac{10^{i-1}-1}{9}\),这利用了等比数列求和性质。)
N8. 线性同余方程 (Linear Congruence Equation)
- 问题:给定\(a, b, n\),求方程\(ax \equiv b \pmod n\)的所有解。
- 步骤:
- 设\(g = \gcd(a, n)\)。
- 同除最大公约数:若\(g \mid b\),方程两边同除以\(g\),得到\(a'x \equiv b' \pmod{n'}\)。
- 其中\(a' = a/g, b' = b/g, n' = n/g\)。
- 若\(g \nmid b\),则原方程无解。
- 求解:求出\(x \equiv x_0 \pmod{n'}\)(通常利用扩展欧几里得算法求解\(a'x + n'y = b'\))。
- 所有解:在模\(n\)意义下,原方程共有\(g\)个解,形式为:\[x \equiv kn' + x_0 \pmod n, \quad k \in \{0, 1, \dots, g-1\} \]
N9. 循环子群的陪集
- 已知:\(d \mid n\),对于\(\mathbb{Z}_n\)的子群\(H = \langle d \rangle\)。
- 最小非负代表元:\(\{0, 1, 2, \dots, d-1\}\)。
- 陪集判定:给定\(x\),其所在的陪集为\((x \bmod d) + H\)。
H1. 陪集的交与 Poincaré 定理 (Poincaré's Theorem)
设\(H, K \leq G\),证明:
- \(H \cap K\)是\(G\)的子群。
- \([G : H \cap K] \leq [G : H][G : K]\)。
- 若\(\gcd([G : H], [G : K]) = 1\),则\([G : H \cap K] = [G : H][G : K]\)。
证明要点:
- (i) 子群判定:若\(a, b \in H \cap K\),则\(a, b \in H\)且\(a, b \in K\)。由子群一步判定法,\(a^{-1}b \in H\)且\(a^{-1}b \in K\),故\(a^{-1}b \in H \cap K\)。
- (ii) 构造单射:构造映射\(\psi: G/(H \cap K) \to G/H \times G/K\),定义为\(\psi(g(H \cap K)) = (gH, gK)\)。
- \(\psi\)是良定义的且是单射。
- 根据公式\(|HK| = \frac{|H||K|}{|H \cap K|}\),当且仅当\(G = HK\)时取等号。
- (iii) 指数整除性:由于\([G : H \cap K]\)既是\([G : H]\)的倍数,也是\([G : K]\)的倍数,且两者互质,故其至少是\([G : H][G : K]\)的倍数。结合 (ii) 的结论,强制取等。
H2. 有限指数子群性质 (群作用视角)
- 命题:若\(H \leq G\),\([G : H] = n\),证明:\(\forall g \in G, g^{n!} \in H\)。
- 证明:
- 构造作用:考虑\(g\)在左陪集空间\(G/H\)上的左乘作用:\(\psi_g(aH) = gaH\)。
- 置换表示:由于映射是单射(且是对映),\(\psi_g\)本质上是\(n\)个陪集上的一个置换。
- 阶的限制:所有置换构成的对称群\(S_n\)的阶为\(n!\)。
- 结论:根据 Lagrange 定理,\(\psi_{g^{n!}}\)必定是单位变换\(\text{id}\)。
- 即\(\psi_{g^{n!}}(eH) = eH \Rightarrow g^{n!}H = H \Rightarrow g^{n!} \in H\)。
- 推论:若\(H \trianglelefteq G\)(正规子群),则可加强为\(g^n \in H\)。
补充 (Lecturer's Supplements)
- 关于 H1 (iii) 的直观理解:这在数论中对应于:如果一个数既是\(a\)的倍数又是\(b\)的倍数,且\(\gcd(a,b)=1\),那它一定是\(ab\)的倍数。
- 关于 H2 的深度:这个证明引入了群表示论的初步思想——将抽象群作用于集合上转化为置换。这在证明一些关于有限指数子群的存在性问题(如正规核 Normal Core)时非常有用。
- 线性同余方程组:N8 是处理单个方程,如果是多个方程(且模数互质),则需要用到中国剩余定理 (CRT)。
H3. 正规化子与陪集 (Normalizer & Conjugation)
- 定义:设\(H \leq G\),定义\(H\)在\(G\)中的正规化子为\(N_G(H) = \{g \in G : gHg^{-1} = H\}\)。
证明要点:
- \(N_G(H) \leq G\)且\(H \trianglelefteq N_G(H)\):
- \(H\)在\(G\)的共轭作用下的稳定子 (Stabilizer) 正是\(N_G(H)\)。由于稳定子必为子群,故\(N_G(H) \leq G\)。
- 由定义,\(\forall g \in N_G(H)\)均有\(gH = Hg\),这满足正规子群的充要条件,故\(H \trianglelefteq N_G(H)\)。
- \(H\)的不同共轭子群个数为\([G : N_G(H)]\):
- 考虑\(G\)通过共轭作用作用于其子群集合。\(H\)的轨道 (Orbit) 即为所有共轭子群。由轨道-稳定子定理 (Orbit-Stabilizer Theorem),轨道大小等于指数\([G : \text{Stab}(H)]\),即\([G : N_G(H)]\)。
- 若\([G : H] = p\)(\(p\)为素数),则\(H \trianglelefteq G\)或\(N_G(H) = H\):
- 利用指数传递性:\([G : N_G(H)] \cdot [N_G(H) : H] = [G : H] = p\)。
- 由于\(p\)是素数,因子只能是\(1\)或\(p\)。
- 若\([G : N_G(H)] = 1 \Rightarrow G = N_G(H) \Rightarrow H \trianglelefteq G\)。
- 若\([G : N_G(H)] = p \Rightarrow [N_G(H) : H] = 1 \Rightarrow N_G(H) = H\)。
H4. 双陪集 (Double Cosets)
- 定理:设\(G\)是有限群,\(H, K \leq G\),则双陪集\(HgK\)的大小为:\[|HgK| = \frac{|H||K|}{|H \cap gKg^{-1}|} \]
- 证明思路:直接考虑\(|HgK| = |H(gKg^{-1})g| = |H(gKg^{-1})|\)。根据乘积准则\(|AB| = \frac{|A||B|}{|A \cap B|}\),结论成立。
- 计算实例:在\(S_4\)中,当\(H, K = S_3\)时,求双陪集\(H(14)K\)的大小:
- \(|H| = 3! = 6\),\(|K| = 6\)。
- 经计算\(|H \cap (14)K(14)| = |\{e, (23)\}| = 2\)。
- 故\(|H(14)K| = \frac{6 \times 6}{2} = 18\)。
H5. (CF 484E) Sign on Fence
- 题目:给定序列\(h_n\),进行\(m\)次询问,求区间\([l, r]\)中长度为\(w\)的连续子段最小值的最大值。
- 解法一:二分 + 主席树。
- 对值域建树,维护区间内“激活”状态(即值\(\geq mid\))的最大连续长度。
- 解法二:线段树 + 整体二分。
- 需仔细维护区间贡献,属于经典操作。
H6. (CF 840D) Destiny
- 讲义前文已提及。核心在于主席树上暴力搜索,利用\(k \leq 5\)保证递归分支极少,从而保证复杂度。
H8. (SPOJ - DQUERY)
- 题目:给定\(a_n\),\(m\)次询问\([l, r]\)中不同元素的个数(\(n, m \leq 10^6\))。
- 经验总结:
- 直接用主席树配合整体二分可能会 TLE(常数或复杂度瓶颈)。
- 巧妙构造:考虑离线算法 + 树状数组。
- 核心思想:对于相同的元素,只在它最后出现的位置贡献\(1\)。从左向右扫描,移动\(r\)时更新树状数组中“最后出现位置”的权值,查询\([l, r]\)的和即可。这种“权值单点更新”配合树状数组非常巧妙。
补充 (Lecturer's Supplements)
- 关于双陪集分解:请注意,双陪集\(HgK\)通常不是群,且不同的双陪集大小可能不同。它们构成了\(G\)的一个轨道分解。
- 关于 DQUERY 的空间优化:如果必须在线查询 DQUERY,可以使用主席树:对于每个位置\(i\),版本\(i\)存储前\(i\)个数,且只在每个数值最后一次出现的位置记为\(1\)。这样版本\(r\)中\([l, r]\)的区间和即为答案。
- H3-3 的直观意义:这个结论告诉我们,指数为最小素因子的子群具有非常强的对称性趋向(往往是正规的)。
H10. 数论求和 (GCD Counting)
- 问题:计算\(\sum_{i=1}^n \sum_{j=1}^n [\gcd(i, j) = k]\),其中\(n \leq 10^{10}\)。
- 推导过程:
- 令\(m = \lfloor n/k \rfloor\)。
- 原式等价于求\(Ans = \sum_{i=1}^m \sum_{j=1}^m [\gcd(i, j) = 1]\)。
- 利用对称性,考虑\(i < j, i > j\)和\(i = j\)三种情况:\[Ans = 2 \sum_{1 \leq i < j \leq m} [\gcd(i, j) = 1] + 1 \]
- 由欧拉函数\(\phi\)的定义,在\(j\)固定时,满足\(\gcd(i, j)=1\)的\(i < j\)的个数为\(\phi(j)\):\[Ans = 2 \sum_{j=2}^m \phi(j) + 1 = 2 \sum_{j=1}^m \phi(j) - 1 \]
- 难点:由于\(n \leq 10^{10}\),\(m\)仍然很大,计算前缀和需要杜教筛 (Du's Sieve) 或 Min_25 筛。
H11. 树上路径第\(k\)小 (K-th Smallest on Tree Path)
- 问题:给定一棵\(n\)个节点的树,\(m\)次询问\(u, v\)间路径上的第\(k\)小权值 (\(n, m \leq 10^5\))。
- 核心解法:主席树 + LCA。
- 建树:每个节点维护从根节点到当前节点路径上权值的可持久化线段树。
- 差分思想:路径\(u \to v\)的权值分布可以通过四个版本的线段树进行叠加/消减得到:\[\text{Target} = \text{Tree}(u) + \text{Tree}(v) - \text{Tree}(\text{LCA}(u, v)) - \text{Tree}(\text{parent}(\text{LCA}(u, v))) \]
- 查询:在上述复合结构上同步进行二分查找。
H12. 子群格与向量空间 (Subgroup Lattice)
问题背景:给定素数\(p\)和整数\(n\),考虑群\(G = \mathbb{Z}_p^n\)(初等阿贝尔群)。
1. 证明\(G\)的子群个数等于\(\mathbb{F}_p\)上向量空间的子空间个数。
- 证明思路:
- \(G = \underbrace{\mathbb{Z}_p \times \dots \times \mathbb{Z}_p}_{n}\)。
- 由于\(\mathbb{Z}_p\)中除单位元外所有元素阶均为\(p\)。
- 在\(G\)上定义标量乘法:对于\(a \in \mathbb{F}_p, v \in G\),\(av\)即\(a\)个\(v\)相加。
- 此时,子群等价于加法封闭且有限,进而等价于\(\mathbb{F}_p\)域上的线性子空间。
2. 计算\(G\)的\(k\)维子群个数。
- 计数原理:\(k\)维子空间个数 = (\(k\)个线性无关向量的取法) / (同一子空间内\(k\)维基的取法)。
- 计算公式(高斯二项式系数):\[\binom{n}{k}_p = \prod_{i=0}^{k-1} \frac{p^n - p^i}{p^k - p^i} \]
3. 举例:\(n=3, p=2\)(即\(\mathbb{Z}_2^3\),元素为\((x, y, z) \pmod 2\),共 8 个)
- 0 维:1 个,即\(\{(0, 0, 0)\}\)。
- 1 维:7 个(非零向量个数 / 1 维基个数),\(\frac{2^3-1}{2^1-1} = 7\)。
- 例如:\(\langle(0,0,1)\rangle, \langle(1,1,1)\rangle\)等。
- 2 维:7 个,\(\binom{3}{2}_2 = \frac{(2^3-1)(2^3-2)}{(2^2-1)(2^2-2)} = \frac{7 \times 6}{3 \times 2} = 7\)。
- 3 维:1 个,即\(G\)自身。
补充 (Lecturer's Supplements)
关于 H10 的超范围内容:
- 如果需要计算\(10^{10}\)级别的欧拉函数前缀和,通常构造狄利克雷卷积\(\phi * 1 = I\)(即\(\sum_{d|n} \phi(d) = n\))。利用杜教筛公式:\[g(1)S(n) = \sum_{i=1}^n (f*g)(i) - \sum_{i=2}^n g(i)S(\lfloor n/i \rfloor) \]这里\(f = \phi, g = 1\),则\((f*g)(i) = i\),公式变为\(S(n) = \frac{n(n+1)}{2} - \sum_{i=2}^n S(\lfloor n/i \rfloor)\)。
- 如果需要计算\(10^{10}\)级别的欧拉函数前缀和,通常构造狄利克雷卷积\(\phi * 1 = I\)(即\(\sum_{d|n} \phi(d) = n\))。利用杜教筛公式:
关于 H12 的对偶性:
- 你会发现\(n=3\)时,1 维子空间个数和 2 维子空间个数相等(都是 7)。这是因为\(\mathbb{F}_p\)上的向量空间具有对偶性:\(k\)维子空间与\(n-k\)维子空间一一对应。
H12-2 公式的简化直观图示:
- 第一个向量\(v_1\)有\(p^n - 1\)种选法;
- 第二个向量\(v_2\)需不在\(\text{span}(v_1)\)中,有\(p^n - p\)种选法;
- 依此类推,分母则是为了排除同一组基构成的相同子空间。
E1. (CF1093E) 两个排列的交集
- 问题:给定两个排列\(a_n, b_n\),进行\(m\)次操作:
- 查询\(a[l_a \dots r_a]\)和\(b[l_b \dots r_b]\)的交集大小。
- 交换\(b\)中的两个元素。
- 转化:由于是排列,元素不重复。按元素计算,转化为二维数点问题:统计点集\((pos_a(x), pos_b(x))\)中落在矩形\([l_a, r_a] \times [l_b, r_b]\)内的点数。
- 解法:
- BIT 套权值线段树:支持动态更新,是在线做法。
- CDQ 分治(时间轴分治):将所有操作按时间排序。处理左半部分修改对右半部分查询的影响。贡献计算方式:\(x\)轴排序,\(y\)轴用 BIT 维护。
E2. (CF1422F) 区间 LCM
- 问题:\(n\)个数,\(q\)次询问\([l, r]\)的最小公倍数 (LCM)\(\pmod{10^9+7}\)。
- 核心思路:\(\text{LCM} = \prod p_i^{\max(e_i)}\)。需动态维护每个区间内质因子幂次的最大值乘积。
- 算法:仿照DQUERY的思路。按右端点排序,动态更新每个质数幂次\(p^k\)的“最后贡献位置”。
- 如图所示,对于\(p, p^2, p^3 \dots\),分别维护它们最后出现的位置。
- 利用可持久化线段树(时间轴线段树)来强制在线查询。
E3. 动态区间第\(k\)小
- 解法:BIT 套权值线段树。经典树套树题目,不再赘述。
E4. 群的自同构群 (Automorphism Group)
设\(G = \mathbb{Z}_n\)。\(Aut(G)\)是指\(G\)上所有自同构\(\psi\)在复合运算下构成的群。
- 证明:\(Aut(G) \cong \mathbb{Z}_n^*\)。
- 证:在\(\mathbb{Z}_n\)中,\(\psi(x) = x \cdot \psi(1)\)。要使\(\psi\)是同构,\(\psi(1)\)必须是生成元,即\(\psi(1) \in \mathbb{Z}_n^*\)(与\(n\)互素)。映射\(\psi \mapsto \psi(1)\)是一个群同构。
- 实例:\(Aut(\mathbb{Z}_{12})\)的元素。
- \(\mathbb{Z}_{12}^* = \{1, 5, 7, 11\}\)。
- 自同构映射为:\(x \mapsto x, x \mapsto 5x, x \mapsto 7x, x \mapsto 11x\)。共 4 个。
- 计算:\(Aut(\mathbb{Z}_2 \times \mathbb{Z}_2)\)。
- 这等价于\(\mathbb{Z}_2\)域上\(2 \times 2\)向量空间的线性变换数(即\(GL(2, \mathbb{F}_2)\))。
- 第一个基向量\((1,0)\)有\(2^2-1=3\)种选法;
- 第二个基向量\((0,1)\)需线性无关,有\(2^2-2^1=2\)种选法。
- 结果:共\(3 \times 2 = 6\)种。
E5. (CF1149C) Tree Generator™
- 问题:用括号序列表示一棵树,进行\(q\)次操作,每次交换两个括号,求树的直径。
- 转化:
- 括号序列中,每个节点的深度\(dep = (\text{左侧 '(', ')' 个数差值})\)。
- 直径公式:在括号序列对应的深度序列上,直径等于:\[\max_{i < j} \{ dep_i + dep_j - 2 \cdot \min_{k \in [i, j]} dep_k \} \]
- 线段树维护:
- 令\(a = dep_i, b = dep_k, c = dep_j\)。我们需要维护\(a+c-2b\)的最大值,其中\(i \le k \le j\)。
- 每个节点需维护以下五项:
- \(A_{max}, B_{min}, C_{max}\)
- \(a-2b\)的最大值
- \(c-2b\)的最大值
- \(a+c-2b\)的最大值
- 通过合并子节点信息实现动态更新。
补充 (Lecturer's Supplements)
- 关于 E1 (CDQ):CDQ 分治虽然不能在线,但其空间复杂度仅为\(O(n)\),在处理大数据量时比树套树更稳健。
- 关于 E4 (自同构群):\(Aut(\mathbb{Z}_2 \times \mathbb{Z}_2)\)其实同构于\(S_3\)。这是一个非常有趣的结论,因为\(\mathbb{Z}_2^2\)的非零元素可以看作三角形的顶点。
- 关于 E5 的技巧:这种将树上距离转化为括号序列/欧拉序上的区间最值问题(RMQ)是处理动态树直径的最强武器。