一些(可能?)有用的东西 & 思想和二级结论
预计第一阶段写完投全站推荐大概 40KB。
计划每个大类下面分出来一些小类,防止找着麻烦。
会放一些相对冷门的算法和数据结构。
但是思想套路和 trick 会更多一点。
推一些东西Orz:
https://www.luogu.com/paste/8hnex65m
https://www.luogu.com/article/2buhtf2w
https://www.cnblogs.com/Zaunese/p/20230807--taolu.html
https://www.cnblogs.com/C202044zxy/p/15126199.html
集训队论文:
https://rusunoi.github.io/books/National-Team-Thesis/2021.pdf
https://rusunoi.github.io/books/National-Team-Thesis/年份.pdf
\textbf{ds}
对于这一部分,强烈推荐 UT 选集。
-
删除
[l,\,r] 的贡献,如果贡献满足交换律,比如删去编号在[l,\,r] 内的点/边,产生的连通性等等。那么可以将序列复制一遍接在后面,此时问题变为保留[r + 1,\,l + n - 1] 的边。P6684。 -
全局平衡二叉树可以写成线段树的写法,
mid置为区间的带权重心即可,本质是用静态 Leafy Tree 维护了全局平衡二叉树。 -
将实儿子设置为子树
\max 最大的儿子,可以得到一种期望复杂度的 Top Tree。Weight Balanced Top Tree。 -
一种动态化线段树,cmd 的博客。
-
莫队的本质是对于
[l,\,r] 形成的二维点集合,在平面上找了一个曼哈顿意义下的近似最小斯坦纳树,根号可以证明是这个问题的一个较严格的上界。而带修莫队就是三维立体空间内找的近似最小斯坦纳树。这也启发我们可以找一些点对作为斯坦纳树的必经点,序列上就是分块然后预处理所有块两两区间的答案,并找到离[l,\,r] 最近的区间扩展到[l,\,r] ,这就是「在线化莫队」,或者称「诗乃莫队」。
给定长度为
n 的两个序列a,\,b ,分别是颜色和权值。q 次询问修改,修改某个位置的颜色,某个位置的权值,或者查询[l,\,r] 内 所有相同颜色的元素的权值和的k 次方 的总和。n,\,q \le 5 \times 10^4,\,k \le 3 。强制在线(tips:模拟赛时拼了两个暴力冲了 86pts/cf)。
-
tips:某种意义上说你甚至可以说 dsu on tree 等链分治
是一类树上莫队。,dsu on tree 是重链从链底到链顶做扫描线。 -
莫队组合数前缀和:组合数前缀和是经典困难问题,多次询问可以考虑莫队。
while (N < q[i].l) sum = (sum * 2 % mod - C(N, M) + mod) % mod, ++N;
while (M > q[i].r) sum = (sum - C(N, M) + mod) % mod, --M;
while (N > q[i].l) --N, sum = (sum + C(N, M)) % mod * iv[2] % mod;
while (M < q[i].r) ++M, sum = (sum + C(N, M) + mod) % mod;
-
线性空间树上线段树合并:树上线段树合并先合并重儿子,再合并轻儿子,最后做修改,当然要加上垃圾回收。可以证明这样的线段树合并空间复杂度是
\Theta(n) 级别的。(单点修6 \times n ,区间修10 \times n )link。tips:似乎可以底层分块直接把权值树空间的\log 去掉,或者直接维护线段树的虚树(压缩 01-trie)。 -
支配:区间内维护的信息是关于
2 \sim 3 个元素的最优化、可行性、区间可行子区间数量等。元素有强限制,考虑有用的点对数量是否不多。CF765F,铃原露露。
rldcot 支配: 对于一个点,它成为 LCA 被贡献,考虑重子树中某个点
由于这样的前驱和后继数量不会超过轻子树大小,总的可能的点对数量不超过
- 启发式分裂:将启发式合并的过程逆向,比如树上,从根结点开始向下递归,根据
f_u 的值暴力减去轻儿子的贡献,得到重儿子的f_{\text{son}_u} 递归重儿子。[NOI2024]登山。
一个小 trick 是对于
树上启发式分裂能干的事情,大部分时候带撤销线段树合并也可以干。九省联考 希望。
我认为它们本质相同。
- Splay 启发式合并的复杂度是
\Theta(n \log n) 的,具体来说合并T_1 和T_2 的时候,将大小较小的树中序遍历后暴力插入另一棵树中,可以证明这样均摊复杂度是\Theta(n \log n) ,因为 Splay 本身就有 Finger Search。
tips:fhq-Treap 也可以做到均摊
-
直角三角形二维数点:以直角和斜边中点分出来矩形,并递归下去分治。这就是 CDQ 分治的本质。
-
不是四毛子的
\Theta(n)/\Theta(1) RMQ: 当然这东西应该是\Theta(\frac{n \log n}{w}) 的。 -
懒惰删除:二进制分组,每层有三个及以上的结点再合并。放到线段树上:
u 满了且同一层的下一个结点满了再合并。Unknown。可以直接去掉插入的均摊。 -
异或线性基的有趣结论:
A 是线性基,则\max\limits_A(x \oplus y) = \max\limits_A(x) \oplus \min\limits_A(y) ,根据这个结论我们甚至可以做到一般图上最大 XOR 和路径的多点查询。 -
不带删尺取:
双指针做删除麻烦的时候可以考虑(比如最值)。
基础的双指针是直接维护
如果困难删除,但是合并容易做到,那么可以考虑不带删尺取。
考虑类似猫树的思想,维护
https://blog.mhxma.tech/2024/02/08/xuexibiji-chijiuhua/
- 动态标号法:维护双向链表,支持在给定结点前后插入,查询两个结点的先后关系。
使用重量平衡树维护,根对应
【模板】后缀平衡树。
- 肥结点:每个结点维护修改的时刻,查询直接二分。
整个 WC2024 第一课堂只听懂了数据结构开头的几个部分。
- 可合并持久化的 fhqTreap 合并:不能直接复制结点,否则会有大量结点
\text{key} 相同导致复杂度假掉。合并可以按\frac{\text{siz}_x}{\text{siz}_x + \text{siz}_y} 的概率将x 放在根。因为同时会复制树形态所以复杂度未知(似乎 lxl 都没证明出来,但也可以证明现阶段无法被卡掉)。
upd:已经有数据卡掉了,可以宣布这种写法 SPFA 了。
可以写 WBLT 做到复杂度严格正确的可合并持久化。
图论
- 树的重心
-
所有点到重心的距离和是最小的,跟点权和边权无关。
-
合并两棵树,新的重心在原来两棵树的重心在新树的连线上。P4299。
-
增加一个叶子,重心至多移动一步。
-
任意根,任意 dfs 序排行一半的结点祖先链中一定包含重心,如果难以维护 dfs 序,则随机一个点,有一半的概率祖先链包含重心。
- 树的直径
-
直径中点是到其它结点最大距离最小的点,且所有直径都交于这个点。
-
到结点
u 距离最大的点一定是直径端点。
根据上面的结论,到点
u 距离最大的路径一定过直径中点。
-
直径的封闭性:两个树直径分别是
a,\,b 和c,\,d ,合并后的直径还是在a,\,b,\,c,\,d 中选择。 -
推一个感觉很牛的博客。
- LCA & 虚树的一些性质:
NOIP2024 T4 树上查询。
dfs 序和按 dfs 序排序后的相邻点的 lca 构成了虚树的所有点。
包含
树上连续的 dfs 序区间
如果把第一个点和最后一个点也看作相邻的话,那么就不需要减最后的总 lca 深度,答案就是总和除以二再减一。JOISC2023 Day3 Tourism。
- Top Tree:
动态 Top Tree 似乎在 OI 里是没有什么应用场景的。
但基于全局平衡二叉树,有简单构建静态 Top Tree 的方法,对于维护树形态极其强力。
https://www.cnblogs.com/ExplodingKonjac/p/17890636.html
-
水流隔板:考虑最小生成树/重构树/笛卡尔树状物,P5952。
-
Color Coding:随机染色,通过染色区分起点和终点。旅行者,CF2003F。
旅行者那道题的非随机化做法,有一个类似的但更牛的东西。CF1365G,我叫它
- 旧词:最早出处是 LNOI LCA 那道题,具体来说维护编号在
[l,\,r] 内的点关于点x 的 LCA 的信息。LNOI 那道题是求 LCA 的深度和,有做法就是离线下来,r 减去l - 1 的信息化为前缀。对于前缀对x 的信息,就将前缀的点到根的链全部加1 ,再查询x 到根的和。这东西可以直接带权,维护前缀的点到根的差分即可。
所以只要我们的信息可差分就能做,比如我们可以直接让点权为
-
V - E 容斥:对于树上联通块统计,以每个点为中心统计一次,以每条边为中心统计一次,答案就是前者减后者。十二省联考 希望。
-
Tarjan 强连通分量算法做完,强连通分量标号从小到大就是拓扑序逆序。Kosaraju 做完标号从小到大就是拓扑序。因此不需要缩点后再跑一遍拓扑,可以直接用。
-
最短路去负权边:为了避免掉负权边要跑 spfa 导致复杂度爆炸,需要重新建图保证不出现负权。一个方法是将问题对偶,还有一个方法是将边权差分。对偶 ABC214H,差分 ABC232G。
-
网络流的伸缩技巧:将边的容量按
\text{highbit} 分组,从大到小加入边进入残量网络并跑 Dinic,交替忽略反向边,复杂度是\Theta(n^{1.5}m) 。 -
一条边经过的次数上限是两端的
\text{siz} 较小值,对于一类最大化\text{dist}(u_i,\,u_{i + 1}) 的问题可以在带权重心上考虑。 -
对于钦定恰好
k 条边的环/路径,k 极小的时候存在简单维护方法。P8906。 -
毛毛虫剖分:一条路径和任意路径结点在路径外相邻的结点集合。
剖分方法:从
时间复杂度与重剖相同。
知道了这个可以轻松切 NOI2021 轻重边。
-
部分图上博弈,走路径的问题,缩一度点有奇效。P8276。
-
长剖的另一个性质:除了优化关于深度的 dp 之外,长剖还有一个性质。如果从根开始走
k 次,每次走到任意结点,取走物品,同一个结点只能取走一次。那么最大的方案就是走前k 大长链。P8125。 -
广义串并联图:其实就是对一类特殊图的删一度点缩二度点操作,P6790。
-
DAG 链剖分:设
f,\,g 分别是从i 出发的路径树和以i 结尾的路径数,v 是u 的重儿子当且仅当u 连向v ,且v 是u 的f 值最大的后继,u 是v 的g 值最大的前驱。
每次跳轻边,要么
维护 SAM 这种路径数有限的 DAG 极其强力。Border 的四种求法。
-
维护连通性,很多时候考虑关于边的删除时间的最大生成森林有奇效。
-
完全图/特殊稠密图最小生成树的套路:一般来讲只考虑 Kruskal 和 Brouvka 算法(还没见过必须 Prim 的生成树题)。Kruskal 要求做到查询边权排名下一个的边,合并联通块,如果能做到那直接套就好了。Brouvka 类似超级钢琴,需要做到合并联通块和找到联通块向外最小的边。
经典题:Xor MST。
Tree MST:将原图分成两个部分,分别做最小生成树,保留各自最小生成树的边集,并起来再做一遍最小生成树,一定是原图的最小生成树。
于是可以分治计算最小生成树。
-
图上记忆化搜索的技巧:如果寻找的路径可以有环,但不可以
u \to v \to u 这样走,那么可以先记录g_{u} = fa 然后搜索其它结点,搜到u 了,如果还是从g_u 而来就退出,否则搜g_u 。 -
各类遍历序的妙用:维护树上直上直下的链,考虑出栈序有奇效,NOI2014 购票。bfs 序适合解决
u 子树内跟u 距离\le d 的点 GDKOI2023 树。普通的 dfs 序也可以\Theta(n \log n)/\Theta(1) 求 LCA,orz wjz。树跟括号序形成双射,因此可以对括号序的最小表示法哈希来树哈希。
https://www.luogu.com.cn/article/ki71nw88
- 退背包/带删除背包:
f_j \leftarrow f_j - f_{j - w_i} ,枚举顺序从小到大,P4141,CF1111D。
-
最长上升子序列长度乘最长下降子序列长度
\ge n 。 -
同余最短路转圈技巧:考虑体积为
v_i 的物品形成\gcd(v_i,\,m) 个子环,最多增加\gcd(v_i,\,m) - 1 个,给完全背包转两圈就可以 dp 出来。
Alex-Wei 同余最短路的转圈技巧。
-
射线法判定点是否在多边形内,在网格图上也适用。围豆豆。
-
贡献延迟计算:有一类 dp 方法是提前钦定一些东西,或者说贡献延迟计算,我们在一些量变化的时候才根据我们额外维护的东西计算贡献。CSP-S2025 T4,uoj 1005,CF1608F。
贪心,随机化和 \textbf{ Ad-hoc}
- 一类树上带依赖贪心问题,可以考虑合并父亲和权值最大的点。UVA1205。
『EX』卡常
- 内存访问连续:
矩阵乘法可以写成:
rep(i, 1, n) rep(k, 1, n) rep(j, 1, n)
原因是内存访问连续了。
同理 ST 表
- 冷热代码:
x += y; while (x >= mod) x -= mod; 似乎比 x += y; if (x >= mod) x -= mod; 更快。
先咕一下。
一些经典复杂度不可优化题
- 所有你能查阅到的 NP 完全问题和 #P 完全问题。
经典例子如 SAT(有 SETH 这种东西) 和大部分背包问题,整数规划。
一些不那么广为人知的:
-
用若干不相交的三元组恰好覆盖所有点/最多能选出多少三元组。
-
SVP(若干平面向量,非零整数倍线性组合到原点最小距离),CVP(原点改为任意点)。
-
积和式(规约二分图完美匹配计数,因此排列计数题想二分图多半不行)。
- 图同构问题
这个不知道是否 NPC,但没有已知多项式算法。
-
一般图简单环计数
-
一些多项式复杂度不可优化的
-
LCS:
|\Sigma| = \Theta(1),\,\Theta(\frac{n^2}{\log^2n}) 。 -
-
OV(给两组向量,长度均
\Theta(\log n) ,问是否存在a_i 和b_j 正交):如果 SETH 成立,则至少n^{2 - o(1)} 。 -
3SUM 问题(三个集合,问是否能各自选出三个数总和为
0 )。三点共线,三线共点,三等差数列,3XOR。