国庆题目

Nefertari_blog / 2024-10-05 / 原文

Maximize the Largest Component (Hard Version)

  • 题意:

给定一个 \(n\times m\) 的网格,由“.”和“#”字符组成。

如果从该组中的任何单元格开始,通过仅移动到该组中共享一个共同边的另一个单元格,就可以到达该组中的任何其他单元格,则一组“#”单元格形成一个连通分量。其大小为该组中的单元格数量。

在一次操作中,选择任意\(r\) 和任意\(c\),然后将行 \(r\)和列 \(c\) 中的每个单元格设置为 "#"。

问在最多执行一次操作后,可以实现的“#”个单元格的最大连通分量的最大可能大小。

ps:保证所有测试用例中的 $ n \cdot m $ 的总和不超过 $ 10^6 $。

  • 思路:

我们考虑到执行操作不会使答案更劣,所以我们一定会执行这次操作。

考虑到 \(n\times m\leq 10^6\),那么我们可以暴力枚举选择哪行哪列。

考虑到如果在枚举内部统计答案不好做,哥们考虑预处理答案,那么可以单点算贡献。

我们看下一个点会在选哪行哪列时产生贡献。

显然如果该点在原本的图上最左边可到达 \(l1\),最右可到达 \(r1\),最上可到达 \(l2\),最下 \(r2\) 的话,那么哥们会发现,只要我们选的行在 \([l2-1,r2+1]\) 的区间内或所选的列在 \([l1-1,r1+1]\) 的区间内,都可以产生贡献。

那么我们将我们的选择也抽象成一个矩阵,第 \(i\)\(j\) 列记录的就是我们选第 \(i\) 行第 \(j\) 列的答案。

然后就变成一个套路的矩阵中一块的加减法,直接弄一个矩阵差分即可转为 \(O(1)\) 处理,最后再转回来即可,记得特殊处理你选的那行和那列的答案。

时间复杂度 \(O(nm)\)

CF1984F

  • 题意:

有一个长度为 \(n\) 的隐藏数组 \(a_1, a_2, \ldots, a_n\),其元素是介于 \(-m\)\(m\) 之间的整数。

给你一个长度为 \(n\) 的数组 \(b_1, b_2, \ldots, b_n\) 和一个长度为 \(n\) 的字符串 \(s\),字符串由 \(\texttt{P}\)\(\texttt{S}\)\(\texttt{?}\) 组成。

对于从 \(1\)\(n\) (含)的每个 \(i\),我们必须有:

  • 如果是 \(s_i = \texttt{P}\)\(b_i\)\(a_1\)\(a_i\) 的和。
  • 如果 \(s_i = \texttt{S}\)\(b_i\)\(a_i\)\(a_n\) 的和。

输出使得数组 \(a\) 符合要求的将 \(s\) 中的所有 \(\texttt{?}\) 替换为 \(\texttt{P}\)\(\texttt{S}\) 的方案个数。

由于答案可能很大,因此输出答案对 \(998244353\) 取模的结果。

ps:\(2\leq n\leq 2\times 10^3\)

  • 思路:

可以先从简单入手,我们先考虑没有 \(?\) 的情况,

那么我们手玩一下会发现,我们一定能得到数列的总和,因为只要第一个是 \(S\) 或者最后一个是 \(P\) 或者 \(s\) 中有一个 \(PS\) 就一定能得到总和。

然后哥们手玩一下这些限制的关系(\(sum\) 为数列和):

  1. \(PP\) 限制了 \(b_i-b_{i-1}=a_i\),而 \(a_i\) 是有范围的(下同)。

  2. \(SP\) 限制 \(sum+b_i+b_{i-1} = a_i+a_{i-1}\)

  3. \(PS\) 限制 \(sum=a_i+a_{i-1}\)

  4. \(SS\) 限制 \(b_{i-1}-b_i=a_i\)

那也就是说,如果我们真的知道这个 \(sum\),我们就可以用 dp 求出方案数。

观察到 \(n\) 的范围,我们可以直接枚举这个 \(sum\) 在那个位置出现(即上文提到的 \(sum\) 的出现方式),然后 dp 即可,时间复杂度 \(O(n^2)\)