ds小寄
DS
当个表格放在这里,表示 \(ds\) 的使用范围,有更好的做法就来吊打我吧
下文不区分 \(n,m\)
Problem
区间加,单点查
差分之后转为下面的情况
单点加,区间和
\(bit\) 做到小常数 \(\log\)
单点加的基本都可以用 \(bit\),不过需要倍增,比如全局 \(rank\) 也是可以做的
区间除法/开根
显然,\(O(\log V)\) 次操作后就变成常数了(开根是 \(O(\log\log V)\) 次),势能分析发现暴力是 \(O(n\log V)\) 的,如果有可能是势能增大的操作需要谨慎使用
区间加线段,单点问一次函数最值
就是李超树,可以 \(O(n+m\log n)\)
单点插入
平衡树即可,一个 \(\log\)
动态维护凸包
用平衡树维护斜率,做到一个 \(\log\)
按 dfs 序遍历树数颜色
用线段树合并做到 \(O(n\log n)\)(启发式合并也是可以的,也都不难写)
区间众数
\(O(n\sqrt n)\) 预处理,\(O(\sqrt n)\) 在线询问
可以偷懒写 \(O(n^\frac{2}{3}m)\) 的
区间逆序对/本质不同逆序对
可以在线的和上面一个复杂度,不过要是可以离线就用莫队吧
区间第 K 大
主席树即可做到 \(O(n\log n+m\log n)\)
单点修,区间第 K 大
树套树做到 \(O(m\log^2n)\) 或者分块做到 \(O(m\sqrt n)\),因为常数的限制,两者运行表现差不多
单点插,单点修,区间第 K 大
树套树这里要三个 \(\log\),分块还是 \(O(\sqrt n)\) 的
区间所有子区间
一般都可以莫队,那么是 \(O(m\sqrt n)\) 的
如果关于 \(\min\) 或 \(\max\),可以考虑笛卡尔树,有时有更快的做法
LCA&LA&RMQ
纯纯的四毛子,\(O(n+m)\),不过运行速度上和 \(O(n\log n+m)\) 的差不太多(RMQ甚至慢一点)
区间翻转/循环平移
可以定期重构,这样是 \(O(n\sqrt n)\) 的
如果用 \(splay\) 或者 \(treap\) 就可以做到 \(m\log n\)
区间取最大值/历史最大值
名字挺多的算法,反正就是势能分析做到一个 \(\log\)
(区间)最大子段和
维护左边的最大前缀和,右边的最大前缀和,区间的答案,线段树即可做到 \(O(n+m\log n)\)
区间加,区间最大子段和
分块可以做到 \(O(n\sqrt n+m\sqrt n)\)
区间 chkmax,区间最大子段和
线段树维护,记录一下最大前缀变长的临界点,势能分析发现不会变短,然后还是 \(O(n\log n+m\log n)\)
K 维数点
用 cdq 做到 \(O(n\log^{k-1} n)\),或者 KDT 做到 \(O(n^\frac{2k-1}{k})\),\(k\) 很大的时候两者其实差不多
区间复制
用可持久化平衡树倍增的维护,可以做到 \(O(m\log n)\)
维护生成树
可以直接 LCT 的话就是 \(O(m\log n)\) 的
动态图连通性
用 AAA 树可以做到 \(O(m\log^2m)\)
动态最小生成树
据说可以 Top Cluster 分块做,具体我也不太会
区间加有线性递推式的数列,区间和
直接维护转移矩阵,线段树即可,\(O(nk^3+mk\log n)\)
多项式函数全局最值,区间修改
首先要只知道 \(n\) 个多项式相交的段数基本是 \(O(n)\) 的,更严格的界要去看 Davenport-Schinzel 序列,这就很吃数学了,和本文没有什么关系
用 KTT 暴力维护,不带修是 \(O(n\log^2 n +m)\) 的
如果修改只有一次函数,那么可以做到 \(O(n\log n+m\log^2n+q\log n)\)
如果修改还有二次函数,那么可以做到 \(O(n\log^2n+m\log^3n+q\log n)\)
用这个可以做到区间加,区间最大子段和的 \(O(n\log^3n+m\log^3n+q\log n)\) 的做法
Trick
线段树的空间
\(r-l= O(\log n)\) 时可以直接暴力展开,最后复杂度不变,空间少 \(20\%\sim30\%\)
分块的端点
这个存下来,用的时候直接访问可以省下除法
分散层叠
不太会用,qwq

浙公网安备 33010602011771号