正睿二十连测
B
赛后:\(30min\)
有一个大小为 \(2 \times n\) 的网格,\((i, j)\) 的颜色为 \(a_{i, j}\),一次操作可以将 \((1, 1)\) 所在的极大四连通同色连通块染为任意一种颜色 \(c\)。问至少需要多少次操作才能使整个网格变为同一种颜色?
每次操作可以刻画成从 \((1, 1)\) 开始向右扩张。
但是显然不是所有点都需要经过,如果我们经过了一个第 \(i\) 列的 \(x\),那么前面的所有颜色为 \(x\) 的格子都会被改掉。所以如果我们经过了一个 \(x\) 在网格中最靠右的位置,前面的 \(x\) 都会被扩到,而如果没有经过只需要最后花费 \(1\) 的代价即可。
所以这个问题其实可以看成一个从 \((1, 1)\) 走到 \((1, n) /(2, n)\) 的路径,路径上相邻格子若颜色不同则有 \(1\) 的代价,如果没有经过某种颜色的最后一个格子(\(i\) 最大的)就需要额外的代价。
然后就可以直接 DP 了,令 \(dp_{i, 0/ 1}\) 表示路径走到了第 \(i\) 列第 \(1/ 2\) 行所花费的最小代价。转移如下。
for (int i = 1; i <= n; i++) {int v0 = dp[0][i - 1] + (i > 1 && a[i] != a[i - 1]); // 从第 i - 1 列走过来int v1 = dp[1][i - 1] + (b[i] != b[i - 1]);bool f = (a[i] != b[i]);dp[0][i] = min(v0 + (lst[b[i]] == i && f), v1 + f); // 如果 (1, i) 是 a[1][i] 中最后一个就有额外的代价。dp[1][i] = min(v1 + (lst[a[i]] == i && f), v0 + f);
}
时间复杂度:\(O(n)\) 。
这个题麻烦的点就是染了一种颜色,改变了一些点,可能出现 \((i, j)\) 被扩张到了,\((i, j - 1)\) 却没有,可能需要多一次代价来染。解决方式是对于每种颜色只需要关心是否经过最后的格子,经过就可以把之前所有的为这种颜色的都改掉。然后题目就变成了一个路径问题,可以 DP 了。
C
赛时花了 \(1h20min\) 过了。
给定 \(n\) 个数 \(a_1 \sim a_n\),问有多少个区间 \([l, r]\) 满足 \(a_l \sim a_r\) 的任意两个非空子序列的 \(\text{lcm}\) 都不相同。
\(1 \le n \le 2 \times 10^5, 1 \le a_i \le 10^6\)
先来考虑一个区间有贡献的充要条件是啥?
有一个必要条件,对于每个 \(a_i\) 都有一个质因子 \(p\) 使得 \(p\) 的指数比其他所有数都要高。否则全集和去掉全集去掉 \(a_i\) 的 \(\text{lcm}\) 是一样的。而且他也是一个充分条件,这样是否包含它的 \(\text{lcm}\) 在 \(p\) 的指数不一样,\(\text{lcm}\) 也就不一样。
赛时想到这里,我想到的是对于每个 \(a_i\) 的质因子用单调栈找到一个合法区间 \([L_{i, p}, R_{i, p}]\),那么 \(L_{i, p} \le l \le r \le R_{i, p}\),对于每个 \(a_i\) 只需要满足其中一个即可。然后我就想从大到小枚举 \(l\),有些 \(L_{i, p} = l + 1\) 的区间就失效了,用线段树单调修改 \(a_i\) 最大的 \(R_i\),然后最后的 \(r \ge \min\limits_{i = 1}^ n\{ \max R_{i, p} \}\)。
题解的做法是从小到大枚举 \(r\),若 \([l, r]\) 合法那么 \([l + 1, r], [l, r - 1]\) 也合法,因此对于每个 \(r\) 找到最小的 \(l\)。用双指针扫一遍,快速维护一个区间是否合法,可以维护每个质因子的最大指数及出现位置。
时间复杂度:\(O(n \log ^2 V)\)。实际上最多 \(O(6n \log V)\),每个数最多 \(6\) 个质因子。
赛时以为对于每个数求出每个 \(p\) 往左最多多少,往右多少,\(L_i = \min L_{i, p}, R_i = \max R_{i, p}\) 然后转化成一个经典模型。后面发现对于每个 \(p\) 有一个单独的区间。如果这么做那么 \(L_2 = 1, R_2 = 3\),实际上是两个个区间 \([1, 2]\) 和 \([2, 3]\)。
10 6 9