树
prufer 序列
CF156D Clues
prufer 序列,还需要推一点 式子。
CF917D Stranger Trees
没有想到 \(n^2\) 的 qwq。可以考虑二项式反演,就变成了钦定 \(i\) 条边的问题。
然后如果知道每一个联通块的大小就是上面的问题了。让dp[i][j][k]
表示在 \(i\) 的子树内,有 \(j\) 个联通块,目前还没有加进去的联通块大小为 \(k\) 的方案的联通块乘积。这个可以 \(n^4\) 转移。
然后从乘联通块大小相当于从联通块中放一个球的方案数。让f[i][j][k]
表示在 \(i\) 的子树内,有 \(j\) 个联通块,\(k\) 表示目前这个联通块有没有放入球的方案数。这个可以 \(n^2\) 转移。
P5219 无聊的水题 I
每一个 \(deg = k\) 的点在 \(prufer\) 序列中的出现次数 \(= k - 1\)。直接 \(EGF\) 得到式子 \((\sum\limits_{i = 0}^{k - 1} \frac{x^i}{i!})^n [x^{n - 2}] (n - 2)!\)
克鲁斯卡尔重构树
P4768 [NOI2018]归程
先求 \(1\) 节点到 \(x\) 节点的最短路 \(ans_x\) (著名卡 \(\tt SPFA\) 题, 要用 \(\tt dijkstra\))。
构建克鲁斯卡尔重构树 (每条边按 \(a\) 排序), 然后看 \(v\) 的 \(k\) 次祖先的 \(a\) 值小于等于 \(p\), 且 \(k\) 最大。
答案就是这 \(k\) 次祖先的重构树中的子树最小的 \(ans_x\)。这东西是可以在做克鲁斯卡尔的时候做掉的。
P4899 [IOI2018] werewolf 狼人
建立两颗克鲁斯卡尔重构树,然后在上面的 \(dfs\) 序上做主席树就好了
CF1408G Clusterization Counting
首先这张图是邻接矩阵。其次跑一遍 kruskal 重构树,顺便判断一下重构树上的节点能不能成为一个团。然后再用 \(dfs\) 序变成一个区间,然后求一下区间覆盖种类数就好了。这东西可以 dp 解决。
最小生成树
一张图的最小生成树的 每种边权出现次数 以及 联通性 一定。
Boruvka : 每一次一个联通块向距离他最短的联通块合并,直到所有的联通块都缩成一个。
CF1305G Kuroni and Antihype
这题把边的权值变成两个点的权值,然后跑一遍 \(kruskal\) 算最大生成树即可。
P4180 [BJWC2010]严格次小生成树
这题只要做一次最小生成树,然后统计一下 \(LCA\) 上的最大值和次大值即可。
CF888G Xor-MST
这题跑一遍 Boruvka 即可。这样是 \(n log^2\) 的,过得去(((
正解貌似是 dfs ?
CF632F Magic Matrix
跑一遍最小生成树,判断一下两点之间的连边是不是最小生成树上两点间的最大值即可。
CF891C Envy
考虑最小生成树使得了边权小的边出现的次数大,也就是一张图的最小生成树的 每种边权出现次数 以及 联通性 一定。因此可以对于每一种边权单独考虑。
那么考虑对于每一条边维护出如果连接了比他 严格 更小的所有边,连的是哪两个联通块。查询的时候对于每一种边权连一下这两个联通块,如果出现环就判无解。
这可以用可撤销并查集维护。
树的重心
在一张边权为正的树上,让 \(d(x)\) 表示 \(\max\limits_{i=1}^{n} dis(x, i)\),让 \(d\) 最小的作为重心,从所有点出发的最长路径都经过重心
CF348E Pilgrims
可以证明所有朝圣者的路径都会经过中心点。对于再中心的哪一边单独处理,那么答案就可以 \(dfs\) 得出。
CF516D Drazil and Morning Exercise
从大往小,每次加入 \(d(x) = k\) 的点,删除 \(d(x) > k + l\) 的点。删除点不会产生联通性变化,因为删除的点距离重心更远。
虚树
P2495 [SDOI2011]消耗战
虚树板子题。
CF1073G Yet Another LCP Problem
考虑到 \(\tt SAM\) 上的两个前缀的 \(\tt lcp\) 是他们 \(\tt LCA\) 的 \(\tt len\) 值,那么在虚树上做 \(dp\) 即可。
CF1111E Tree
考虑按照 \(\tt dfs\) 序 \(dp\),\(dp_i\) 表示现在分成了 \(i\) 组的方案数。如果一个数有 \(t\) 个祖先在这 \(k\) 个结点内,那么 \(dp'_i = dp_{i} \times (i - k) + dp_{i - 1}\)。
虚数只是为了 $\log $ 统计祖先个数
CF1292D Chaotic V.
奇怪的题目。把 \(1! ... n!\) 依次插入,然后求他们的虚树即可快速计算答案。考虑怎么计算 \(i!\) 和 \((i-1)!\) 的 \(lca\) ?
只要找到 \(i!\) 和 \((i-1)!\) 的最大的不同的因数 \(t\),就是 \(i\) 的最大因数。然后求一下 \((i-1)!\) 中 \(\le t\) 的质因数的个数即可。用树状数组可以维护。
dfs 树
CF521E Cycling City
如果这张图不是一个仙人掌,那么这张图就存在答案。(否则有两个相交的环,然后环上两个相交的点之间有至少三条路径)
建立 \(dfs\) 树,把反祖边的两端的边的 \(cnt++\),得到每一条边的经过次数。对于 \(cnt \ge 2\) 的边,进行处理。
对于这样的边的深度较低的端点,向下 \(dfs\) 找到这两个环。