CF1327 简要题解
不知道说啥了,直接写题解吧(
- A
手玩一下可以发现,前 \(k\) 个奇数的和等于 \(k^2\),在此基础上,可以进行任意次 \(+2\)。因此无解当且仅当 \(n<k^2\) 或 \(n\not\equiv k\pmod 2\)。
- B
模拟找到每个公主匹配的王子,如果完美匹配则无解。否则,任选一位未被选择的公主和王子就是答案。
- C
将所有棋子向左移动 \(m-1\) 步,再向上移动 \(n-1\) 步,此时所有棋子都集中在左上角的格子。暴力让它扫过每个格子即可。总步数 \((m-1)+(n-1)+(nm-1)<2nm\)。
- D
对于置换中每一个循环 \((q_1, q_2, \ldots, q_l), q_i=p_{q_{i-1}}, q_1=p_{q_l}\),显然对于任意的 \(k\),\(p^k\) 中从循环中某个位置出发向前走,不会走出这个循环。考虑可能的 'Infinite Path' 的长度,其必然是 \(l\) 的一个约数。枚举它的长度 \(d\) 和起点 \(q_x, 1\leq x\leq \frac{l}{d}\),则这样的循环在 \(k=\frac{l}{d}\) 时,恰好第一次出现在置换中。暴力判断每个侯选答案是否合法即可。
对于一个长度为 \(l\) 的循环,枚举的总复杂度是 \(O(d_l\cdot l)\),其中 \(d_i\) 是 \(i\) 的约数个数。
- E
对于 \(1\leq i< n\),长度为 \(i\) 的 block 有两种可能:
- 左端点 \(\in [2, n-i]\),此时它的两边不能与它相等,方案数有 \((n-i-2+1)\cdot 9^2\times 10\times 10^{n-i-2}\) 种。
- 左端点 \(\in \{1, n-i+1\}\),此时它只有一边不能与它相等,方案数有 \(2\times 9\times 10\times 10^{n-i-1}\) 种。
对于 \(i=n\) 的,显然只有 \(10\) 种。
(所以这题的意义是什么……)
- F
经典套路题,不过连想带写也花了不少时间。
首先每一位的取值是独立的,先枚举位数,转化为 \(01\) 串上的若干区间,每个区间要求:
- 至少有一个 \(0\);
或者
- 全是 \(1\)。
求方案数,每一位乘起来即可。
要求全是 \(1\) 的区间可以差分维护,扫一遍确定哪些位置被染了 \(1\),并将这样的区间两端缩起来。具体实现时,设 \(s_i\) 表示原序列中 \([1, i]\) 内有 \(s_i\) 个位置染了 \(1\),则可以将一个原序列上的区间 \([l, r]\) 映射成 \([l'=l-s_{l-1}, r'=r-s_{r}]\),表示原序列中第 \(l'\) 到第 \(r'\) 个没有被染成 \(1\) 的位置,注意 \(l'>r'\) 时无解。设 \(n'=n-s_{n}\)。
剩下的区间,发现如果存在 \(l_1\leq l_2\) 且 \(r_1\geq r_2\),则只要 \([l_2, r_2]\) 的条件满足,则 \([l_1, r_1]\) 的条件一定也满足,可以直接删掉 \([l_1, r_1]\),使得剩余的区间都满足 \(l_i<l_{i+1}\) 且 \(r_i<r_{i+1}\)。
考虑容斥,枚举区间的某个集合 \(S\) ,满足 \(S\) 中区间内全是 \(1\),贡献为 \((-1)^{|S|}\cdot 2^{n'-f(S)}\),其中 \(f(S)\) 表示 \(S\) 中区间的并集长度。
直接容斥显然不太能接受,考虑 dp。设 \(f_i\) 表示排好序的前 \(i\) 个区间中,最后一个被选入容斥集合 \(S\) 的区间是 \([l_i, r_i]\),每种方案当前的贡献为 \((-1)^{|S|}\cdot 2^{r_i-f(S)}\),所有方案的权值和(注意这里的贡献与上面略有出入)。转移的时候枚举上一个区间 \(j\),发现有两种情况:
- \(r_j<l_i\),也就是说两个状态之间存在着长度 \(\geq 0\) 的间断,将 \([l_i, r_i]\) 加入 \(f(S)\) 时的贡献恰好就是 \(r_i-l_i+1\),因此这一部分的贡献是 \(-2^{l_i-r_j-1}\cdot f_j\)。
- \(r_j\geq l_i\),也就是说两个状态是直接相连的,将 \([l_i, r_i]\) 加入 \(f(S)\) 后,右端点移动的距离和 \(f(S)\) 新增的长度相等,因此这一部分的贡献是 \(-f_j\)。
注意到左右端点都是严格递增的,因此两个部分的分界点是唯一的,并且随着 \(i\) 增大而增大。
将第一部分的贡献化成 \(2^{l_i-1}\times (-2^{-r_j}\cdot f_j)\),只需维护括号内的部分,前缀和优化一下就可以做到 \(O(1)\) 转移。
注意答案等于 \(\sum_{i=0}^{m'} f_i\cdot 2^{n'-r_i}\),其中 \(m'\) 代表第一类区间数量,\(r_0=0, f_0=1\)。
- G
看错数据范围了……虽然看对了可能也不太会做(
实际上思路还是比较清晰的,只要能想到用 AC 自动机处理多串匹配相关的 dp。(主要是看错数据范围之后,串长和有 \(10^6\) 那么多……怎么看着也不像能套个状压 dp 的样子啊(x
对所有模式串建出 AC 自动机,并处理好每个节点跳 \(\operatorname{fail}\) 过程中经过节点的权值和。
设 \(f_{i, j, S}\) 表示考虑母串的前 \(i\) 个位置,目前停留在 AC 自动机的 \(j\) 位置,已选的字母集合为 \(S\) 的最大值。
这个状态设计,单是状态数就已经不可接受。但是不难发现,整个过程中,只有不超过 \(14\) 次决策,其余过程都是沿着自动机的边按部就班地走。因此,只考虑 s[i]='?'
的位置,中间的过程实际上与 \(S\) 无关,只与 \(j\) 有关。因此可以枚举每个 \(j\),暴力地在自动机上走,保存每一个 \(j\) 会走到的位置和途经的权值和。对于每一个 \(S\),都可以直接套用。
于是就做完了,复杂度 \(O\left((\Delta2^{\Delta}+|s|)\cdot \sum |t_i|\right)\)。