2025年3月杂题集
目录
- P6623 [省选联考 2020 A 卷] 树
- P6018 [Ynoi2010] Fusion tree
- AT_abc391_g [ABC391G] Many LCS
- P10614 BZOJ3864 Hero meet devil
- P11844 [USACO25FEB] Friendship Editing G
- AT_abc314_g [ABC314G] Amulets
- AT_abc238_g [ABC238G] Cubic?
- AT_abc235_g [ABC235G] Gardens
P6623 [省选联考 2020 A 卷] 树
题目大意:给定一棵有根树,对于每个点 \(x\) 求其子树内每个点的「权值与到 \(x\) 距离的和」的异或和。
我们可以考虑自底往上做,用 01-Tire 维护子树内的异或和,每到达一个新的点就将权值插入到 Trie 中,同时合并每个儿子的 Tire。
那么现在的问题是对 Trie 上的数全局加 \(1\) 后维护异或和。考虑全局加 \(1\) 就是把一个数的低位若干个 \(1\) 变成 \(0\) 然后再补上一个 \(1\)。那么从低位往高位建 01-Trie。只要一直递归 \(1\) 的边,然后对于走到的每一个点把 \(0\) 边的儿子挪到 \(1\) 边即可。
实现上就是先交换左右儿子,然后递归 \(0\) 边。这样我们就把 \(O(\log V)\) 全局加 \(1\) 做完了。
另外对于合并 Trie 就像线段树合并那样做即可,用线段树合并的复杂度分析,复杂度一个 $\log $。
P6018 [Ynoi2010] Fusion tree
做法依旧是全局加 \(1\) 的 01-Tire。固定根以后,我们的 01-Trie 只维护儿子的,然后父亲的权值就暴力改。改一个点的权值时,记得要把父亲的 Trie 也改了,加一个点的儿子时需要在这个点打上懒标记用于求某个儿子的值。
AT_abc391_g [ABC391G] Many LCS
DP 套 DP。
考虑设 \(f_{i,j}\) 表示大串 \(T\) 匹配到第 \(i\) 个数,\(S\) 匹配到第 \(j\) 个数时最长公共子序列。
有转移:
我们发现有性质:对于 \(f_i\),相邻 \(j\) 的 \(f_{i,j}\) 差分为 \(0\) 或 \(1\),于是可以用一个二进制数表示 \(f_i\)。
因为对于不同的 \(i\) 没有额外的限制,所以可以 \(O(2^nn\sum)\) 求出每一种 \(f_i\) 加上一个新字符后转移到哪一个 \(f_i'\),其实就是构建了一个自动机。其中 \(\sum\) 代表字符集大小。
然后就在自动机上做 \(m\) 轮转移即可,复杂度 \(O(2^nm\sum)\)。
P10614 BZOJ3864 Hero meet devil
和上面那道题是一模一样的。
AT_abc293_h [ABC293Ex] Optimal Path Decomposition
考虑二分答案,然后就变成了判断可行性。
设 \(f_{i,0/1/2}\) 表示点 \(i\) 已经与其 \(0/1/2\) 个儿子颜色相同时,要使子树合法的,从 \(i\) 出发的最小路径颜色数。
那么转移枚举儿子,然后看是否与儿子颜色相同,对于儿子 \(v\),只有 \(f_{v,0/1}\) 能参与转移。
那么有转移:
- 选为不同颜色,当 \(f_{x,i}+f_{v,j}\le K\) 时,\(f'_{x,i}\gets\max(f_{x,i},f_{v,j}+1)\)。
- 选为相同颜色,当 \(f_{x,i}+f_{v,j}-1\le K\) 时,\(f'_{x,i+1}\gets \max(f_{x,i},f_{v,j})\)。
最后判断根节点是否合法即可。
复杂度 \(O(n\log n)\)。
P11844 [USACO25FEB] Friendship Editing G
首先特判掉没有边的情况,否则整张图连通。
然后考虑题目要求的限制即任意两个点的最短路小于或等于 \(2\)。
假设确定一个点 \(x\),和与 \(x\) 最短路为 \(1\) 的点集 \(S_1\),与 \(x\) 最短路为 \(2\) 的点集 \(S_2\)。
有如下连边规律:
- \(S_1\) 中的点与 \(x\) 都有边, 否则最短路不为 \(1\)。
- \(S_2\) 中的点与 \(x\) 都没有边,否则最短路不为 \(2\)。
- \(S_2\) 中的点两两之间都没有边,否则有一条边则 \(x\) 与这条边的端点无边,不符合题意。
- \(S_2\) 中的点每个点与 \(S_1\) 中的每个点都有边,否则对于 \(y\in S_1,z\in S_2\),因为 \(x,y\) 一定有一条边,如果 \(y,z\) 之间无边则不符合题意。
- \(S_1\) 中的边成为一个子问题。
如果枚举 \(x\),再枚举 \(S_2\) 是会算重的,但我们发现 \(x\) 与 \(S_1\) 的关系、\(S_2\) 与 \(S_1\) 的关系是相同的,所以可以把 \(x\) 并入 \(S_2\)。
那么就是一个枚举子集的 DP。
现在问题是求边数,求一个点集内部的边 \(F_S\) 直接暴力地做即可,复杂度 \(O(2^nm)\);求点集 \(S\) 与点集 \(T\) 之间的边数可以用 \(F\) 容斥,即 \(F_{S\cup T}-F_S-F_T\)。
总复杂度 \(O(3^n)\)。
AT_abc314_g [ABC314G] Amulets
对于每个前缀,求出如果都击杀那么所需的最小护符个数。
那么用两个 set
维护使用护符击杀的(\(S\))与通过扣血击杀的(\(T\))。
每当扣血量大于等于 \(H\) 时可以先考虑交换 \(S\) 中的最小值与 \(T\) 中的最大值。如果还是不行就增加一的护符数。
时间复杂度 \(O(n\log n)\)。
AT_abc238_g [ABC238G] Cubic?
考虑哈希,首先对于每一个数分解质因数。我们给每一个质数随机两个权值 \(v_1,v_2\),然后循环赋值 \(v_1,v_2,v_1\oplus v_2\)。
这样就可以保证每个质数出现三的倍数次后异或和必为 \(0\),那么预处理一个前缀和后就可以 \(O(1)\) 处理询问。
时间复杂度 \(O(V\log V)\)。
AT_abc235_g [ABC235G] Gardens
考虑容斥,我们枚举一个 \(i\),表示指定 \(i\) 个盒子必为空。则答案为:
考虑设 \(f_i=\sum _{j=0}^A \binom {i} {j}\)。我们需要递推 \(f_i\),由于 \(\binom i j=\binom {i-1}{j-1}+\binom {i-1} j\),所以可以得到 \(f_i=2\times f_{i-1}-\binom A{i-1}\)。
复杂度 \(O(n\log n)\)。