To do list #1 : CEOI 2019
Building Skyscrapers
题目链接
注意到要求字典序最大是从
把建造变成拆除,考虑拆除顺序的字典序最大即可。
显然存在方案的充要条件是所有大楼均连通,那么在拆除过程中,一旦发现图不连通,则无解,说明刚才拆错了。
那么一栋大楼能够被删除当且仅当:
- 它能到达无穷远处。
- 它不是割点。
考虑这个东西该怎么判。
先判断前者。我们不妨把整张网格图建出来,有尚未被拆除的大楼的点标记为黑点,反之为白点。最外层的白点是可以到达无穷远处的,与可以到达无穷远处的白点四连通的点是可以到达无穷远处的。
可以用并查集来合并,不过其实没必要。因为我们注意到每次将一个黑点变成白点的时候一定只会将至多一个白色连通块合并到能到达无穷远处的连通块上,而不会对其他白色连通块产生影响,每个点的合并次数都是
可是这个平面是
然后考虑后者如何判断。无向图动态删点维护连通性,这东西做不了一点。不过好在这道题比较特殊,是在一个网格图上,那么只需要判一下周围八个点的状态即可。
一个点是割点有且只有两种情况:
A*B
A#B
A*B
A*B
*#B
BBB
其中 # 代表这个点,* 代表一个白点,A 和 B 对应两个不同的区域。
如果两个 * 在同一个连通块里,且 A 区域和 B 区域都至少有一个黑点,那么这个 # 是割点。
实际上情况有六种,第一种情况旋转后总共有两种情况,第二种情况旋转后总共有四种情况。我们可以预处理打表把这六种情况都记录下来,这样在代码实现上更加简洁。
注意到每次只有删除的点的周围的八个点的状态可能会变,这确保了我们的操作数是
Dynamic Diameter
题目链接
带权树求树上直径,可以使用树形 DP 来做。现在边权动态变化,考虑使用动态 DP 来做。
首先一个 trick 是边权不好处理,我们转换成点权来做。把每条边的边权挂在儿子节点上当做点权即可。
设
接下来边权带修,考虑如何 DDP。
首先按照 DDP 的标准套路,我们把
定义一种广义矩阵乘法,用加法代替原本矩阵乘法中的乘法运算,用
需要注意的是:树的叶子节点的转移矩阵应该是全
Cubeword
题目链接
首先枚举正方形的边长,然后考虑对于某个边长该怎么做。
首先注意到只有角上的字母会重复使用,因此我们可以直接枚举八个角上的字母,然后两两计算贡献即可。
令字符集大小为
考虑怎么优化这个玩意。
注意到对于一个顶点,它会且仅会与三个顶点共用一条边。如果我们确定了另外三个与它共用一条边的顶点填什么并计算出了贡献,那么这个顶点填什么都无所谓了。
这样就可以减掉一个顶点的枚举,降低一维的复杂度。
那么最多可以减掉几个顶点的枚举呢?
注意到,只需要枚举正方体底部正方形对角线上的两个点和顶部正方形另一条对角线上两个点即可,剩下四个点都与刚才枚举过的某三个点共用一条边。
于是复杂度被降低到了
Amusement Park
题目链接
考虑一个 DAG 在边全部反转之后仍然会是 DAG,那么如果有一种反转
那么怎么求总方案数呢?
考虑状压 DP,设
我们知道 DAG 里一定有一些入度为
枚举
但问题是这样做会算重复。比如我们枚举的一个合法的
考虑一个老生常谈的容斥,当
于是做完了,最终复杂度
Magic Tree
设
如果不收割
如果收割
二者取
暴力转移,复杂度
考虑线段树合并。
发现收割
区间推平下界的具体做法是:维护每个区间的
加法操作的标记很难下传,标记永久化即可。
Scissors and Tape
计算几何 + 大模拟,不会且懒得写,摆了。