9.14 模拟赛

A. 矩形

小 C 有一个 \(n \times n\) 的矩阵,每个格子有一个颜色 \(a_{i, j}\le n\)

给定 \(k\),你需要计算出对于所有格子,以这个格子为左上角的最大正方形,满足内部颜色数量不超过 \(k\)

\(n \le 500\)

枚举左上角 \(i, j\),二分正方形的边长,然后用 \(|a|\) 的复杂度求这个正方形内有多少颜色。复杂度 \(\mathcal O(n^2 |a| \log n)\)。能拿 \(70\)

考虑如何去掉 \(\log\)。在对角线上双指针即可。

B. 删除序列

很好很好的算答案方式。

小 D 有一个长度为 \(n\) 的序列。如果序列不是非降的,他会选择一个元素删去,直到序列变成非降的,这时停止操作。求操作序列种类数,对 \(10^9+7\) 取模。

两个操作序列不同,当且仅当它们长度不同或者某一次操作删除的元素位置不同。

\(n \le 2000,1 \le a_i \le 10^9\)

这个问题的难点在于,如果此时序列已经非降了那么此时必须停止。我们考虑如果没有这个限制的问题:

小 D 有一个长度为 \(n\) 的序列。如果序列不是非降的,他会选择一个元素删去,直到序列变成非降的,这时可以选择停止操作,也可以不停止。求操作序列种类数,对 \(10^9+7\) 取模。

我们考虑原序列的任意一个上升子序列对答案的影响,即有多少种将其它元素删除的方式,使得最终整个序列只剩这个子序列。

令这个上升子序列长度为 \(i\)。显然这个的答案是 \((n - i)!\),即其它元素可以任意选择顺序删除。

暴力枚举这个上升子序列仍然是指数复杂度。考虑 DP。

\(f(i, j)\) 表示有多少上升子序列以 \(i\) 结尾且长度为 \(j\)。转移显然:

\[f(i, j) = \left\{\begin{matrix}1 &, j=1 \\ \sum_{k=1}^{i-1}[a_k \le a_i]f(k,j-1) &,j \ne 1 \end{matrix}\right. \]

可以用树状数组轻易优化至 \(\mathcal O(n^2 \log n)\)

考虑统计答案。令 \(g(i) = \sum_{j=1}^i f(j, i)\),即有多少个上升子序列的长度为 \(i\)。那么答案为:

\[\sum_{i=1}^n g(i) \cdot (n - i)! \]

至此我们用 \(\mathcal O(n^2 \log n)\) 的复杂度通过了弱化版。

我们考虑原问题比弱化版的答案少在了哪些地方。即考虑一个上升子序列什么时候产生的贡献变小。

对于一个长度为 \(i\) 的上升子序列 \(s\),如果存在 \(j\)长度为 \(i + 1\) 的上升子序列完全包含它,那么当小 D 通过若干次删除操作得到这 \(j\) 个子序列后,游戏应当在此时停止。不难发现只有这种情况会导致 \(s\) 不产生贡献。

所以答案比弱化版少了:

\[\begin{matrix} \sum_{s,j} j \times (n-(i+1))! \\ \Tiny s\text{ is an increasing subsequence of length }i\text{ of }a.\\ \Tiny \text{There are }j\text{ increasing subsequences of length }i+1\text{ that completely contain }s. \end{matrix} \]

暴力枚举 \(s\) 还是指数复杂度。

显然每个 \(s\) 对应的 \(j\) 的和为 \(g(i + 1) \cdot (i + 1)\)。这是因为一个长度 \(i + 1\) 的上升子序列中含有 \(i + 1\) 个这样的 \(s\)

所以答案为:

\[\sum_{i=1}^n\left[ g(i) \cdot (n-i)! - g(i+1)\cdot (i+1)\cdot(n-i-1)! \right] \]

posted @ 2024-09-14 15:51  2huk  阅读(86)  评论(3编辑  收藏  举报