预处理的艺术
以下默认合并答案是 \(O(1)\) 的
\(O(n\alpha(n))-O(1)\) 的ST表
这个非常 \(naive\),对于规模为 \(O(n)\) 的问题,我们以 \(O(\log n)\) 为块长分块,块间建立ST表,每个点存到自己所在块端点的答案,递归到 \(O(\frac{n}{\log n})\) 个大小为 \(O(\log n)\) 的子问题,直到块长为 \(O(1)\)。
然后发现就是 \(O(n\alpha(n))\) 的预处理了,因为只会有 \(O(\alpha(n))\) 层这样的结构,现在的问题是确定询问属于那一层。
只需要预处理出对于所有可能的长度,比其恰好大的块长,这样的询问要么在块内,要么恰好在相邻的两块间,于是就 \(O(1)\) 解决了。
然后猫树和ST表没有什么区别,一样的做就可以了。
The Method of Four Russians
已经普及啦
大概就是分块,小的把所有可能的情况预处理出来,大的用数据结构块间维护。
\(\pm1\) RMQ
就是 \(a_i-a_{i-1}\in\{-1,1\}\) 的区间最值
我们发现块长设为 \(\frac{\log n}{2}\) 的话,本质不同(差分不同)的块只有 \(2^{\frac{\log n}{2}}=\sqrt n\) 种,于是可以 \(O(\sqrt n\log^2 n)\) 的暴力处理所有块内的答案,然后这个显然是不到 \(O(n)\) 的,块间建ST表就可以了。
LCA
用欧拉序,以深度为权值,转化为 \(\pm1\) RMQ
RMQ
建笛卡尔树,转化为 \(LCA\)
LA
这个不太一样,我们考虑长链剖分,
然后我们就做到了 \(O(n\log n)-O(1)\)
如果我们可以把树的大小变为 \(O(\frac{n}{\log n})\) 那不就可以了。
于是我们把大小恰好不超过 \(\frac{\log n}{4}\) 的子树减下来,系数是 \(\frac14\) 保证了不同的子树的数量不超过 \(\sqrt n\),于是又做完了。
树上问题
显然,子树询问容易转化为序列问题,于是这里主要处理链上操作。
树上并查集
就是每次把儿子并到父亲上。
我们用 \(Top\ Cluster\) 分块,块的大小为 \(O(\log\log n)\),枚举本质不同的块合并其中一个点之后会变成哪种块。
块间就同时用路径压缩和按秩合并,然后就做到线性了。
链询问
树剖(当然是轻重链剖分),重链上建猫树,维护每个点到向上所有链顶的答案,这样是 \(O(n\log n)\) 的。
现在我们需要 \(O(1)\) 确定要查到哪个链顶,这只需要从 \(lca\) 向上跳一个 \(top\) 再向下走一个就可以了。
如果我们对链顶分块,就可以做到 \(O(n\log^\epsilon n)-O(1)\) 的复杂度,不过我觉得除了 \(\epsilon=\frac12\) 可能有点实际意义,其他的取值都不太有用。(你这个东西有用吗)