T2 数组开小了本地测极限还没测出来,痛失 \(50\) 分!
T1 P8338 [AHOI2022] 排列
把排列拆成置换环,那么一个 \(f\) 就是选两个不在一个环的点,把两个环拼起来,然后对所有环长求 \(\text{lcm}\)。
显然环长相同的环可以放在一起考虑,于是只有 \(O(\sqrt n)\) 个不同的环,暴力枚举两个环,维护每个质因子的最大、次大、三大幂次就可以 \(O(Tn\omega(n)+n\log n)\) 了。
T2 P8339 [AHOI2022] 钥匙
考虑计算一对钥匙和宝箱对答案的贡献,可以发现 \((x,y)\) 这个钥匙-宝箱对合法,当且仅当 \(x\) 和 \(y\) 的颜色都是 \(c\),且 \(x\rightarrow y\) 路径上,把颜色 \(c\) 的钥匙看作左括号,箱子看作右括号,形成了一个合法括号序列。
于是枚举每种颜色建出虚树,然后枚举钥匙得到 \(5n\) 个合法对。可以发现一个合法对可以造成贡献当且仅当路径起点在 \(x\) 子树内,终点在 \(y\) 子树内,二维数点即可。
复杂度 \(O(n\log n)\)。
T3 P8340 [AHOI2022] 山河重整
首先有一个很显然的 \(O(n^2)\) dp:
令 \(f_{i,j}\) 为使用了前 \(i\) 个数字,目前最多可以凑出前缀 \([1,j]\) 的方案数,转移只需要新加入的区间拼的上就好了。
实际上,转移时的限制可以写作“集合中 \(\leqslant k\) 的数之和要 \(\geqslant k\)”。于是我们考虑容斥,我们找到第一个不满足的位置 \(p\) 进行转移,并乘上 \(-1\) 的系数。
此时有一个很好的性质,由于 \(p\) 之前的位置都满足性质,所以小于等于 \(p-1\) 的数之和一定是 \(p-1\)。
那么就可以把 dp 变成一维的,令 \(f_i\) 为 \([1,i]\) 内的数,和恰好为 \(i\) 的方案的容斥系数之和。它的计算可以用正常的整数拆分减去 \(f\) 带来的容斥转移。
这一类型的 dp 有一个很经典的优化到背包的方法,我们可以类似 P6189 [NOI Online #1 入门组] 跑步,一次要么加入一个钦定不满足的数字,要么给全局加若干次一,可以发现只会加入至多根号个数字,所以做这个 dp 的复杂度是 \(O(n\sqrt n)\) 的。
但是我们在转移前必须把转移过来的 dp 值提前计算完成,可以使用类似半在线卷积,每次先求出前一半的 dp 值,再转移给后一半。
复杂度是 \(n\sqrt n+\frac{n\sqrt n}{2}+\frac{n\sqrt n}{4}+\cdots=O(n\sqrt n)\) 的。
T4 P8341 [AHOI2022] 回忆
哈哈,我不会多项式级别做法!
首先删掉被包含的路径,然后删掉子树内没有路径结尾的点,称操作后路径结尾是叶子的路径是好路径。
考虑子树 \(x\) 内部且经过 \(x\) 的路径,显然我们只需要关心子树内的好路径,令其儿子 \(u_1,u_2,\cdots,u_k\) 子树内好路径结尾数分别为 \(v_1,v_2,\cdots,v_k\)(不妨令其为降序),不难发现一次操作最多覆盖两个儿子的好路径。
那么根据经典结论有:若 \(v_1\leqslant \sum_{i=2}^k v_i\),那么可以在 \(\lceil\frac{\sum_{i=1}^k v_i}{2}\rceil\) 次操作内覆盖完全。
否则我们一定是贪心地把 \(v_{2,\cdots k}\) 与 \(v_1\) 抵消,我们给答案加上 \(\sum_{i=2}^k v_i\)。我们引入“免费路径”这一概念,表示某棵子树内可以免费地覆盖一些路径。于是我们可以记录“\(x\) 子树多出了 \(\sum_{i=2}^k v_i\) 条免费路径”并递归 \(u_1\)。
然后考虑一条以 \(x\) 为开头的路径,不妨令其结尾为 \(y\)。若 \(y\) 的祖先有免费路径,就将最深的一个有免费路径的祖先的免费路径移动到 \(y\) 上。否则给答案加一并在 \(y\) 上新建一个免费路径。
各类维护都可以用树状数组实现,时间复杂度 \(O(n\log n)\)。