2025 刷题计划 - 根号算法
A. CF1806E Tree Master
允许离线又是根号算法,再看到这些区间询问,考虑莫队。
把树拍平成括号序列是树上莫队的常见处理手法,求出树的欧拉序,这样每个节点就有一个进的序和一个出的序,整棵树变为一个长度为 \(2n\) 的序列。记节点 \(i\) 的入序为 \(L(i)\),出序为 \(R(i)\),发现对于一组询问 \(l,r\),锁定区间 \([R(l),L(r)]\),这个区间中只出现一次的序所代表的节点就是 \(l\) 到 \(r\) 路径上的节点,剩下的贡献是从 \(\operatorname{LCA}(l,r)\to1\) 的路径提供的,可以预处理。
莫队就可以做了,维护区间内每个深度的点的 \(\sum a_i\) 和出现次数,如果遇到了出现次数为一的点就加答案,否则减答案。
B. P10680 [COTS 2024] 双双决斗 Dvoboj
ST 表的妙用,发现 \(l,l+1,\dots,l+2^k-1\) 这个形式和 ST 表简直不要太像,但真正让我们能用 ST 表的原因是这个 \(|A-B|\) 是可重复贡献的。
但这题要求动态,现在我们的复杂度是查询 \(O(1)\)、修改 \(O(n\log n)\),直接根号分治均摊复杂度。具体而言,ST 表的倍增长度最大为 \(\sqrt n\),这样修改时我们就可以 \(O(\sqrt n\log\sqrt n)\) 修改包含单点的区间,查询的时候 \(O(\sqrt n)\) 递归查询即可。
C. P10408 「SMOI-R1」Apple
看到这个下意识想到 \(O(2^{\operatorname{popcount}(n)})\) 遍历子集,但显然过不去。重点是它很难优化,实际上,这题需要用到旁门左道 SOS DP,它可以更快速地求出指定数位的子集。既然数位能指定,所以就有优化空间。现在的复杂度是 \(O(2^n)\) 修改、\(O(1)\) 查询,考虑根号分治均摊复杂度。具体而言,SOS DP 只维护后十位的子集,前十位我们遍历就可以,复杂度均摊为单次 \(O(2^{n/2})\)。
H. P7432 [THUPC 2017] 钦妹的玩具商店
其实不难。这题一眼多重背包,但对每个询问做一次多重背包是 \(O(nm)\) 的。考虑分块预处理,设 \(f_{i,j,k}\) 表示编号为 \(k\)、只选 \([1,i-1]\) 和 \([j+1,B]\) 这两个块的区间的答案。查询的时候散块跑多重背包,整块直接加答案就行,单次复杂度 \(O(\sqrt nm)\)。
I. P5268 [SNOI2017] 一个简单的询问
经典一拆四,莫队维护四个值。细节注意。