题解-ARC117
ARC117A God Sequence
先 \(A, A - 1, ... 1, -1, -2, ... -B\)。减少最小值或增加最大值控制总和。 aclink(0)。
ARC117B ARC Wrecker
除了不同的数会变得相同,其他相对大小不会改变。
所以设高度取值(包括最低点 \(0\))排序后的集合为 \(a\),那么可以独立选择把每个间距(\(a_{i + 1} - a_i\))减到多少,所以答案就是 \(\prod (a_{i + 1} - a_i + 1)\)。
ARC117C Tricolor Pyramid
必然要转化运算 \(\to a \otimes b = -(a + b)\bmod 3\)。
然后组合数算贡献即可。然后这里还有个小问题(我搞了约 \(30\) 分钟),就是处理阶乘时如果 \(n \ge 3\),就会 \(n! \equiv 0\pmod 3\)。所以维护一个数的同时维护它当中因数 \(3\) 的个数。
ARC117D Miracle Tree
无根树必须找根。必然有一个点 \(u\) 满足 \(E_u = 1\),就设它为根。
然后对于两条叶子到根的链,它们受到根的距离的约束必然没有互相之间距离的约束大,但是又不足以大到要把 \(E_u\) 跟深度反着标。所以标法必然是维护一个时间,DFS 整棵树,在一个节点进栈的时候时间 \(+1\),出栈的时候时间 \(+1\),然后一个节点的 \(E_u\) 为进栈时间。
然后会发现最大的标号的节点(终止节点) \(v\) 的标号是 \(2n - dep[v]\)。所以根和终止节点取直径的两端即可。
ARC117E Zero-Sum Ranges 2
没有毒瘤,比 AtCoder,更喜欢,出线头 dp。
很明显转前缀和。相当于长度为 \(2n + 1\) 的序列 \(s_i\),\(s_0 = s_{2n} = 0\),\(|s_{i + 1} - s_i| = 1\)。一个区间 \([l, r)\) 和为 \(0\) 当且仅当 \(s_l = s_r\)。
必然要 dp。然后由于对于 \(x\) 如果有 \(d\) 个 \(s_i = x\),就有 \(\frac{d(d - 1)}{2}\) 个和为 \(0\) 的区间,所以考虑一层一层来 dp。又因为后若干层组成的若干个不连通的峰和当前的绝对位置没有关系,所以考虑到线头 dp(这种 AtCoder 风格的毒瘤 dp 我自己是永远想不到的啊)。
设 \(f[i][j][k]\) 表示当前前缀高度(具体是多少不重要)有 \(i\) 个点,\(j\) 个和为 \(0\) 的区间,\(k\) 个不连通的峰。转移比较简单,枚举 \(i, j, k, d\),表示新一层有 \(d\) 个点,然后用组合数隔板法把 \(d\) 个点分成 \(k + 1\) 份即可。偷个 AtCoder 官方题解图:
最后枚举 \(0\) 线及以上的峰和 \(0\) 线以下的峰合并统计答案即可。时间复杂度 \(\Theta(n ^ 5)\)。
ARC117F Gateau
容易想到搞成前缀和然后差分约束。但是由于题目是个环差分约束很麻烦,所以一个比较好的办法是二分答案 \(s_{2n}\),这样对于 \(i \ge n\) 的条件 \(\ge a_i\) 就转化为了 \(s_i - s_{i - n} \le s_{2n} - a_i\)。
如果直接跑最短路解决差分约束直接 TLE,所以考虑到(其实我也不知道该考虑到什么才能想到这个鬼东西,太玄学了)所有条件都是对于长度为 \(n\) 的区间的,可以想办法搞出 \(s_n\)。
假如 \(s_n\) 已定,可以贪心求出 \(s[1, n)\) 和 \(s[n + 1, 2n)\)(先令 \(s_i = s_{i - 1}\),\(s_{i + n} = s_{i - 1 + n}\),然后如果 \(s_{i + n} - s_i > s_{2n} - a_{i + n}\) 就增加 \(s_i\),如果 \(s_{i + n} - s_i < a_{i}\) 就增加 \(s_{i + n}\),这样的调整能保证 \(s\) 单调不减),如果 \(s_{n - 1} \le s_n\) 且 \(s_{2n - 1} \le s_{2n}\),那么就得到了一个合法的序列 \(s\) 了。
如果 \(s_n\) 太小,\(s_{n - 1} \le s_n\) 很难解决,如果 \(s_n\) 太大,\(s_{2n - 1} \le s_{2n}\) 很难解决(很明显贪心求出的 \(s_{2n - 1}\) 和 \(s_n\) 是单调的)。由于两个条件是相互独立且相互抵抗的,所以可以考虑二分满足第一个条件的最小 \(s_n\) 或满足第二个条件的最大 \(s_n\) 然后看看满不满足另一个条件。如果不满足,那么这个 \(s_{2n}\) 就不满足条件。
别忘了贪心求出的 \(s_{n - 1}\) 和 \(s_{2n - 1}\) 是会爆 int
的,而且别忘了 \(a_0\) 和 \(a_n\) 的限制(用于规定 \(s_n\) 的二分边界)。时间复杂度 \(\Theta(n\log ^ 2 n)\)。