定期重构

概述

  • 有时,我们维护的数据结构是静态的,但题目却要求加/删。

  • 如果题目满足元素互相独立,则考虑定期重构吧!

    • 加入:将加入但还未整合到数据结构中的元素放入一个栈中,询问时暴力扫这个栈,到达阈值后将栈整合入数据结构,重新 build 一遍即可。

    • 删除:考虑反演,我指的是算贡献(这要求贡献满足可减性,不过都独立了,应该都是可减的),将被删除的单独开一个数据结构,对正和负贡献的两个数据结构分别做定期重构即可。

  • 考虑到复杂度平衡,一般较常见的“定期”是根号次操作。可以基于启发式合并来做启发式重构。替罪羊树有着特殊的重构周期,其依赖平衡因子 α,这主要和其作为树的递归性有关。

根号重构

启发式重构

  • 启发式重构是一种颇特殊的定期重构方式。其尝试将合并过程规约到启发式合并的时间复杂度下——也即每个元素只会参与 O(log) 次合并,从而获得比根号重构更好的时间复杂度。

  • 显然这是不容易的。考虑一个不允许插入的数据结构,不妨取其的构建复杂度为 O(siz)siz 为元素个数。当我们把小的数据结构合并到大的中时,小的一方的复杂度是正确的,但既然没法插入则复杂度为 O(sizA+sizB),大的一方的复杂度会炸。

  • 解决办法:让两者的 siz 一样大就好了——回到“每次合并 siz 翻倍”的证明中去!

    • 按二进制维护若干个数据结构,第 i 个的 siz2i。显然至多有 O(log) 个数据结构。

    • 每次新加的元素单独开一个数据结构,然后模仿二进制进位过程,不断合并 siz 相同的数据结构。

    • 显然其符合启发式合并的复杂度分析。于是,我们有了 O(mlogm+Qlogm) 的优秀复杂度,m 为插入的元素个数,Q 为询问次数。

    • 注意,其优越性依赖 m,Q 的平衡,若 Q=mm,则 O(mm+Q) 的根号重构反而复杂度更优。

CF710F String Set Queries

  • 题意略。

  • 一眼 AC 自动机,但是 AC 自动机是离线的。

  • 考虑使用启发式重构。不删除,另开负贡献数据结构做减法。

  • 总复杂度 O(|S|logn)

  • 但实际上空间开不下,必须动态开点,动态开点的 AC 自动机想 destruct(我指的是撤销 trie 图)恶心得要死,我根号重构逃课算了(当然这一做法不仅复杂度劣,常数可能还大...)。

  • 本题还有一个有趣的根号分析+哈希的做法:通过字符串哈希来做匹配,容易证明不同的长度至多有 n 种,于是暴力就是 O((|S|)32) 的。当然也可以根号分治一下,把里面的短串插进 trie 来代替哈希,但显然并不必要。

posted @   未欣  阅读(100)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示