最近一些题的题解瞎口胡(22年暑假)
1. 摩尔庄园
用树形 dp 模拟网络流。
记 \(a\) 为 \(x\) 走向 \(fa(x)\) 的次数,\(b\) 为 \(fa(x)\) 走向 \(x\) 的次数,\(flw(x) = a - b\)。
这样在从 \(x\) 走向 \(fa\) 时:
- 如果 \(flw(x) < 0\),表示有更多次从 \(fa\) 走向 \(x\),那么这一次费用为 \(-1\),表示和之前一次从 \(fa\) 走向 \(x\) 的费用抵消了(网络流的思路)。
- 否则,无法抵消,费用为 \(1\)。
从 \(fa\) 走向 \(x\) 时是类似的。
从下往上进行 \(\rm Update\),计算从 \(x\) 到其子树中有食物的地方,费用最小是多少,并记录下那个点的编号。
每读入一只拉姆的位置,就计算其费用并更新图中的费用。
2. Centroids
一个优秀的性质是以重心为根时所有点的子树大小都不会超过 \(\dfrac{n}{2}\),因为根本身就是如此。
对于节点 \(u\),这时只有 \(u\) 上面的部分有可能超过 \(\dfrac{n}{2}\),那么最优策略是选择其中最大的不超过 \(\dfrac{n}{2}\) 的子树,把它接到 \(u\) 上,设这一部分的大小为 \(cut_u\),那么剩下的部分就是 \(n - siz_u - cut_u\),如果仍然大于 \(\dfrac{n}{2}\),那么无法成为重心;否则可以。
于是问题转为如何求 \(cut_u\)。
记录 \(mx_u\) 为 \(u\) 子树内(不包括 \(u\))最大的不超过 \(\dfrac{n}{2}\) 的子树大小,当从 \(u\) 转移到 \(v\) 时:
但如果 \(v\) 的子树就是 \(u\) 的最大的不超过 \(\dfrac{n}{2}\) 的子树,这时 \(mx_u\) 是不能选的,所以我们应该记录最大值和次大值 \(mx_{u,0}, mx_{u, 1}\)。这样转移就变成了
3. 由乃与大母神原型和偶像崇拜
发现 \(n\) 个数的和容易重,但平方和就不好重。所以维护区间最小 \(mn\)、区间最大 \(mx\)、区间和 \(sum1\)、区间平方和 \(sum2\)。
首先判断 \(mn + len - 1\) 是否等于 \(mx\),然后求 \(\sum\limits_{i = mn}^{mx} i\) 是否等于 \(sum1\),\(\sum\limits_{i = mn}^{mx}i ^2\) 是否等于 \(sum2\)。
模数直接 $\rm unsigned\ long\ long $ 自然溢出,注意等差数列与平方和都要除一个数,把它乘到式子另一边去。
当然你怕不保险也可以加上立方和,这样就几乎卡不掉了(
4. Book of Evil
记录 \(mx_{u, 0}\) 和 \(mx_{u, 1}\) 分别表示 \(u\) 到子树内的 damage 的最大和次大距离,且保证二者 不在同一条到 \(u\) 的路径上(即 不在同一分支),\(dis_u\) 表示 \(u\) 到子树外的 damage 的最大距离。三个数组的初始值均为 \(-\infty\);特别地,当 \(u\) 节点本身存在 damage 时,\(mx_{u,0}\) 和 \(mx_{u, 1}\) 有初始值 \(0\)。
\(mx\) 的更新比较显然:(\(v\in \{son_u\}\))
- 当 \(mx_{v,0} + 1 > mx_{u, 0}\) 时,次大值变为 \(mx_{u, 0}\),同时让 \(mx_{v, 0} + 1\) 作为新的最大值;注意最大值和次大值不能在同一分支上,所以不用 \(mx_{v, 1}\) 再去更新次大值。
- 否则,\(mx_{u, 1} \gets \max(mx_{u, 1}, mx_{v, 0} + 1)\)。
第二遍 Dfs
,计算 \(dis\) 值:
- 如果 \(mx_{v, 0} + 1 = mx_{u, 0}\),则最大值在 \(v\) 的子树内,不能用来计算,\(dis_v \gets \max(dis_u,mx_{u, 1}) + 1\)。
- 否则 \(dis_v \gets \max(dis_u, mx_{u, 0}) +1\)。
最后判断 \(\max(mx_{u, 0}, dis_u)\) 是否 \(\le d\) 即可。
5. Valid Sets
定义连通图的代表点为图内权值最大的点,若有多个点权值相等则取编号最小者。
那么每一个连通图都必然 有且只有一个 代表点,我们枚举这个代表点 \(rt\),求出满足要求且以 \(rt\) 为代表点的连通图数量,这样就能保证不重不漏。
具体地,以 \(rt\) 为根开始 Dfs,设 \(dp_u\) 表示在 \(u\) 的子树内,包含节点 \(u\),且代表点为 \(rt\) 的满足要求的连通图数量,初始值为 \(1\)(只选 \(u\))。
当从节点 \(u\) 到其子节点 \(v\) 时,先判断 \(v\) 的加入是否仍满足 \(rt\) 是代表点,如果不是,\(dp_u\) 不变,否则递归进入 \(v\) 的子树,回溯后,\(v\) 的子树的连通块可选可不选,
最后,以 \(rt\) 为代表点的数量就是 \(dp_{rt}\),将所有加起来即是答案。
6. Snuke Line
对于一个 \(d\),如果其存在 \([l, r]\) 的倍数,则必存在正整数 \(k\),使得
所以只要找到所有 \(d\),满足
一个一个枚举 \(d\) 是不行的,可以使用整除分块,对于 \(\left\lfloor\dfrac{l - 1}{d}\right\rfloor\) 和 \(\left\lfloor\dfrac{r}{d}\right\rfloor\) 均相等的 \(d\),对它们的答案全部加 \(1\),具体可以用差分。这个整除分块的区间是 \([1, l - 1]\)。
对于 \([l, r]\) 的 \(d\),\(\left\lfloor\dfrac{l - 1}{d}\right\rfloor\) 必然为 \(0\),而 \(\left\lfloor\dfrac{r}{d}\right\rfloor\) 至少为 \(1\)。
对于 \((r, +\infty)\) 的 \(d\),二者的值均为 \(0\),不产生贡献。
总时间复杂度为 \(\Omicron(n\sqrt{m} + m)\)。
7. Addition and Subtraction Hard
AT2273 [ARC066C] Addition and Subtraction Hard
首先有一个很显然的性质:
- 括号只添加在减法后。
推论:如果出现了两个减号,比如
其中 \(A\) 为一个算式,那么第二个减号后,即 \(A\) 中的所有数都可以变成正数。
像
可以变成
除了第二个减号前的 \(9\),其它数全部负负得正成了正数。
所以第一个减号前的数不用动,第一个和第二个减号之间的数全部取反,后面的数全部取正,加起来即是答案。我们所需要做的就是枚举这第一个括号的位置,注意最后还要和不加括号比较。
8. Phoenix and Computers
最后会形成类似 一段手动 + 一个自动 + 一段手动 + …… + 一段手动 的情形。
设 \(dp_{i, j}\) 表示共有 \(i\) 个手动,\(j\) 段手动的开灯方案数,转移方程如下:
其中新开一段可以在其余 \(j\) 段中插 \((j + 1)\) 个空,而不新开一段则在原来 \(j\) 段中挑头或尾开灯共 \(2j\) 种。
最后只有满足 \(i + j - 1 = n\) 的才能产生贡献,因为全部点亮时必定满足 手动个数 + 自动个数 = 总灯数,而自动个数恰为 \((j - 1)\)。
9. 萌萌哒
朴素做法是将 \([l1, r1]\) 中每个点分别和 \([l2, r2]\) 中对应的点并入一个集合,设最后共有 \(k\) 个集合,那么每个集合内都为同一个数,则 \(ans = 9 \cdot 10^{k - 1}\)(首位不为 \(0\)),时间复杂度为 \(\Omicron(n^2\alpha(n))\)。
使用倍增进行优化,设并查集中 \(fa_{i, k}\) 表示以 \(i\) 为左端点的长度为 \(2^k\) 的区间 \([i, i + 2^k - 1]\) 所在的集合的根区间的左端点,比如 \(l_1 = 1, r_1 = 4, l_2 = 5, r_2 = 8\),将区间 \([1, 4]\) 并到 \([5, 8]\) 所在的集合,那么此时 \(fa_{1, 2} = 5\)。
对于一个区间长度为 \(len\) 的区间,直接对 \(len\) 进行二进制拆分处理,比如 \(l_1 = 1, r_1 = 3, l_2 = 4, r_2 = 6\),那么 \(len = 3 = (11)_2\),分别令 \(fa_{1, 1} \gets 4, fa_{3, 0} \gets 6\)。
但是最后查询时是落实到单点上面,所以还需要一次下传,方法是将一个长度为 \(2^k\) 的区间断成两个长度为 \(2^{k - 1}\) 的区间,将两段分别与根的对应两段合并。
时间复杂度为 \(\Omicron(n\log n\cdot\alpha(n))\)。