打板挂掉记录
每天教练查一个模板,每天都写挂。
10.10 LCA
倍增预处理的时候判断 f[u][i - 1]
是否为 0 写成 f[u][i]
了。
for(int i = 1; f[u][i - 1]; i++) f[u][i] = f[f[u][i - 1]][i - 1];
10.11 AC 自动机
如果是要求模式串有无出现的话不用建 fail 树,但是要给暴力跳 fail 跳到的位置增加标记表示下次就不用跳了:
for(int x = p; ~ed[x]; x = fail[x]) ans += ed[x], ed[x] = -1;
10.12 树链剖分
预处理的时候没有设置 sz[u] = 1
。。。
另外线段树求最大值没考虑到有负数,设置的 ans 初值为 0。
void decom(int u, int f) {
fa[u] = f, dep[u] = dep[f] + 1, sz[u] = 1;
for(int v : g[u]) {
if(v == f) continue;
decom(v, u);
sz[u] += sz[v];
if(sz[v] > sz[hc[u]]) hc[u] = v;
}
}
10.13 SPFA
SPFA 判负环有一种更好的方式:cnt[v] = cnt[u] + 1
,详见这篇博客。
10.14 Kruskal 重构树
不按秩合并的话就可以记录树形结构,当然也可以给并查集再加个数组记录在 Kruskal 重构树上的根。
10.17 二分图匹配
草,完全不会写匈牙利了。匈牙利算法其实是一种增量构造,每次贪心的为左部的第 \(i\) 个点创造匹配。设置 vis[u]
才能保证复杂度,正确性显然因为搜过的子树就不必再搜了。我们把尝试增加匹配过程中连出去的边看做虚线,如果最后有一个左部点成功连上了右部未被匹配的点,那么整个递归过程中的虚线变成实线,实线变成虚线,总匹配数量就加一了。
10.18 树的直径
f1[u]
和 f2[u]
的初值应设为 0。
直径是所有点的 f1[u] + f2[u]
取 max。
只能拿 f1[v]
来更新 f1[u]
和 f2[u]
,因为从一个儿子只能有一条路下去。
10.19 树的重心
无事发生.jpg
10.20 树上差分
问题不大。
11.16 中国剩余定理
所以模数为什么要互质?