ARC199
AtCoder Regular Contest++ 199
闲话
是 VP 的,当天脑子十分不好睡了 \(12\) 个小时以上,状态一言难尽。通过了 A 和 D,但是赛时通过率 B > A > C > D,那很诡异了。
首先看 A,注意到 \(0 \leq \max R_i, \max C_i \lt \frac{n}{4}\) 的限制,考虑和整体取反有关,直觉上大概就是因为严格小于 \(n/4\) 或大于 \(3n/4\),所以一次取反前后对应的取值区间肯定是不交的。然后找到一次整体操作的不变量就通过了。
然后看 B,然后看了半小时没有一点头绪,此时我并不知道正反方向操作不是严格可逆的,一直在想非目标集合的元素该怎么删掉的问题。期间试了试 C 然后没看懂它在说啥。
于是看 D,一开始没有看见前缀操作,以为是整行操作然后一眼秒掉之后发现读错题了。想了一会之后获得了一个 \(\mathcal{O}(n^2 \times 2^m)\) 的轮廓线 DP 做法,进一步发现对于列的限制,可以钦定整列均被染黑,此时每个状态和需要被排除的情况构成双射,所以可以直接等价到删掉这些全黑列的子问题,所以可以直接转化为一个上指标和的卷积形式,范德蒙德卷积优化做到 \(\mathcal{O}(nm^2)\),又因为 \(nm \leq 2 \times 10^5\) 所以直接取 \(n,m\) 较小的那个作为实际的 \(m\) 就可以做到 \(\mathcal{O}(nm \sqrt{nm})\)。
问题主要就是,脑子不清楚的时候不会去想别的办法辅助思考,不好评价做 B 题的时候我在干什么,感觉稍微画画图就能过这个题了。
A (构造、Ad-hoc、*2300):
感觉这东西不到紫,至多就是个蓝。个人认为比起 B 题还是简单很多的。
因为操作顺序没有影响,我们只关心某个位置被行操作/列操作次数之和的奇偶性,所以可以分开考虑,分别用调整法刻画出行操作和列操作的必要条件。
首先观察不变量,不难注意到可以固定一行或者一列使其不需要操作,如果在此条件下考虑其他行和列,最后得出的解需要操作这一行/列那么将其他所有的行和列全部取反也可以得到一样的效果。
那么我们考虑固定第 \(1\) 行:
- 因为列操作是全局操作,任意一次对第 \(c\) 列的操作都不改变同一列上两行 \(i,j\) 对应的 \(A_{i,c} \oplus A_{j,c}\) 的取值。
- 因为最终保证 \(R_i, C_j \leq n / 4\),由鸽巢原理,对任意两行 \(i,j\),至少有 \(n / 2\) 个位置 \(k\) 满足 \(A_{i,k} = A_{j,k} = 0\)。
所以只需要求出 \([2,n]\) 内每一行和第一行的相同元素数量,如果小于 \(n/2\) 那么无需操作,大于等于 \(n / 2\) 就必定要操作。
再考虑列操作,只需要看所有行调整完之后,每一列对应的是 \(C_j\) 还是 \(n - C_j\) 即可。如果是 \(n - C_j\) 那么还要确定操作这一列之后,所有受影响的行依旧符合要求。
因为每一步都是必要的,所以直接取反就得到了所有无解条件。又因为行操作、列操作对应的操作条件,对应的一行内 \(1\) 的个数要么是 \([0,n / 4 - 1]\),要么是 \([3n / 4 + 1, n]\),所以取值区间严格不交,可以唯一地构造出一组解。那么充分性也通过构造保证了。
时间复杂度 \(\mathcal{O}(n^2)\)。
D (组合计数、DP、根号分治、*2900):
首先思考如何刻画整个操作过程,发现如果 \((i,j)\) 被染黑,那要么所有 \((x, j), x \lt i\) 均被染黑,要么所有 \((i,y), y \lt j\) 均被染黑。则有一个显然的轮廓线 DP 状物的暴力:令 \(f(i,S)\) 表示考虑前 \(i\) 行,此时前缀全部被染黑的列的集合为 \(S\) 的方案数,同理用 \(g(i,S)\) 表示带权的答案。那么每次转移就相当于对当前行做一个线性 DP,枚举当前这一行每个位置填或不填即可确定端点和行上的操作(因为行操作是对前缀的,所以是 \(\mathcal{O}(n)\) 的枚举),这样可以做到 \(\mathcal{O}(n^2 \times 2^m)\)。
因为这个 DP 实际上并没有用到前缀操作的性质而只是判定你枚举的状态是否符合前缀性质,所以它是可以解决严格强于题目给定操作的问题的,换言之就是还有性质可以用来优化。
注意到,假设当前行的前缀操作右端点是 \(r\),那么 \([1,r]\) 中的所有在 \(S\) 内的列在这一行断开还是不断开是没有区别的,它并不会截断或接上剩余的列上的黑点,换言之对于前 \(i\) 行当前问题和删去 \(S\) 中所有列的问题是一样的,每个局面均构成双射。这启发我们可以将每次 \(i \to i + 1\) 的过程视作转移断点的过程,只需要在扫描线时确定每一列最早需要保留的时间,就可以不重不漏统计所有形态。
具体来说就是令 \(f(i,j)\) 表示染色一个 \(i \times j\) 的子矩形的合法方案数,\(g(i,j)\) 表示对应的黑点数量之和。转移可以直接枚举前缀长度和剩余的黑点的数量,则有 \(f(i,j) = f(i-1,j) + \sum_{x=0}^{j-1} \sum_{y=0}^{j-x-1} \binom{j-x-1}{y} \times f(i-1,j-y)\)。\(g\) 的转移是类似的只不过加了个权重,而因为操作形式是固定的所以权重是可以直接由 \(i,j,x,y\) 算出的,分别从 \(g(i-1,j)\) 继承,以及第一类 \(f\) 转移对应的 \(j \times f(i-1,j)\),以及第二类转移对应的原本保留的 \(i \times y\) 个点以及前缀操作对应的 \(x\) 个点,这部分对应的方案数为 \(f(i-1,j-y)\),与此同时还要继承 \(g(i-1,j-y)\) 对应的原始子问题的答案。
然后你就发现这个转移系数是个上指标和卷积,可以用范德蒙德卷积优化。也就是 \(\sum_{x=0}^{j-1} \sum_{y=0}^{j-x-1} \binom{j-x-1}{y}\) 变成 \(\sum_{y=0}^{j-1} \binom{j}{y+1} \times f(i-1,j-y)\)。对 \(g\) 同理,直接从上一个 \(g(i-1,j-y)\) 继承是完全一样的,唯一不同的是 \(i \times y + x\) 部分需要将 \(f(i-1,j-y) \times x\) 对应的贡献和前一项单拆开来,最后两项的系数分别是 \(\binom{j}{y+1}\) 和 \(\binom{j}{y+2}\) 状物。
这样时间复杂度就做到了 \(\mathcal{O}(nm^2)\),注意到行列操作形式完全一致,所以转置 \(90 \degree\) 不会有影响。由此可以想到直接选 \(\min\{n,m\}\) 作为第二维,就可以保证复杂度不超过 \(\mathcal{O}(nm\sqrt{nm})\)。
浙公网安备 33010602011771号