大师大师,这个凶是什么意思捏
9.27
[QOJ 149] Peru
DP.
好题,但是将区创飞。
令 \(dp_i\) 表示覆盖前 \(i\) 个位置所需要的操作次数,容易得到:
可以很简单做到 \(n\log n\) 但是无法通过。
简单观察可发现转移过程中只有 \(i-k\sim i-1\) 中的后缀最大值对应的下标才有用(\(i-k\) 这个位置特判即可)。
如果没有只能覆盖 \(k\) 个数的限制那么就可以直接使用一个单调栈维护后缀最大值,同时开一个辅助数组记录答案。加上限制后只需要改成双栈即可,每次重构时直接两个栈均分,容易证明均摊复杂度是 \(O(n)\) 的。
有一些细节,区区调了一年没调出来。
IOI2023 Soccer Stadium
DP.
好题,但是将凶创飞。
容易发现最终的图形一定是一个菱形,考虑暴力 dp,令 \(dp_{l,r,x}\) 表示覆盖了第 \(l\sim r\) 行并且所有行中都包含了第 \(x\) 列的最大面积,预处理后可以做到 \(O(n^3)\)。
容易发现很多状态是无用的,观察发现,对于一个 \(r\),有用的 \((l,x)\) 只有 \(O(n)\) 对,因为我们只需要找到每一列从 \(r\) 往上的第一个 \(1\)。
因此可以直接使用 \(dp_{r,x}\) 进行转移,\(dp_{r,x}\) 可从 \(dp_{r-1,x}\) 转移过来,也可以从 \(dp_{r, L_{r,x}}\) 和 \(dp_{r,R_{r,x}}\) 转移,\([L,R]\) 指的是目前所有行覆盖的列的并。
9.28
[集训队作业2018] count
反射容斥神题。
转换为对笛卡尔树数量计数,由于相同值取编号较小为较大值,一个点的左子树中的所有点一定小于这个点,又因为值域为 \([1,m]\),笛卡尔树合法必须满足:从根节点开始走到每一个叶子都不会向左走 \(\ge m\) 次。我们可以证明这个条件是充分的,大致是考虑将一个子树内的所有点同时减一不会影响合法性,最终可以构造出一组点权覆盖 \([1,m]\) 的解。
考虑如何统计这样的笛卡尔树的数量,这里有一个非常牛的 trick:如果 \(u\) 是 \(fa_u\) 的右儿子,则将 \(u\) 变为 \(fa_u\) 的兄弟,然后和 \(fa_u\) 一起往上合,直到遇到第一个向左走的父亲。此时二叉树变成了多叉树,而且你可以发现二叉树和多叉树之间可以一一对应!此时多叉树中的限制变成了 \(w_u\le w_{fa_u}-1\),相当于限制了子树深度 \(\le m\)。
如何统计深度 \(\le m\) 的多叉树数量呢?考虑模拟 dfs 的过程,每次可以选择向下新开一个儿子或者回溯,这样问题就变成了括号序列计数,直接用反射容斥即可。
[JOISC2020]汉堡肉
贪心。
很有启发的一道题,但是写起来是是。
回忆一下一维的最少点覆盖区间问题,我们是每次选取最小的一个右端点然后更新已被覆盖的区间,选最大的左端点统计出的答案也是对的。
回到这道题,依照一维情况的结论,我们可以推断出最小下边界,最大上边界,最小右边界和最大左边界是重要的。先判断一些特殊情况,比如最小右边界大于等于最大左边界,此时可以直接缩成一维的情况,上下边界也是同理。
此时四个边界就完全分开了,容易证明每个边界对应的线上必然要放一个点,你又恰好只有 \(k\le 4\) 个点,指向性非常强。
如果 \(k\le 3\) 那么必然有放在交点上的点,枚举四个焦点,就可以变成 \(k\le 2\) 的问题,\(k=2\) 时可以先选一个矩阵然后不停加矩阵直到交为空,此时一定可以找到一对交为空的矩阵,然后将剩下的矩阵并到这两个上就行。
\(k=4\) 时先判掉有交点的情况,如果有就类似 \(k=3\) 可以直接做,如果没有四条边界上就必然各有一个点。如果一个矩阵与三条边界有交则必然完整包含一条,所以相当于每限制;如果与一条边界有交相当于限制了边界的所在区间,如果与两条边界有交可以用 2-sat 维护互相之间的限制关系,随便前后缀优化一下就行了。

浙公网安备 33010602011771号