2023 联合省选解题报告
[省选联考 2023] 火车站
签到题,乱做即可。做法 \(O(n\log)\) 到 \(O(n)\) 不等。
一些实现可能需要注意细节。
[省选联考 2023] 城市建造
容易发现目标子图与其 \(t\) 个点一一对应,于是只需要对那 \(t\) 个点 dp 即可。
分析性质可以发现,建立圆方树后, \(t\) 个点要么只有 \(1\) 个(该情况不满足题目要求),要么就是若干个满的点双,且构成一个连通块。
于是可以枚举连通块大小上下界 \([L,R]\) ,每次暴力背包,复杂度为 \(O(n^3)\) 。
显然很多状态并不合法,考虑对于一个点的若干儿子,讨论其 size 大小:
- 若其 size \(\lt L\) ,则只能划归为 x 的连通块内。
- 若其 size \(\geq R\) ,则只能作为 \(t\) 个点之一。
- 否则,设不满足上述条件的儿子有 \(cnt\) 个,这些儿子最多只能有一个划归为 x 的连通块,贡献 \(L\) 大小的连通块,对 dp 贡献 \(cnt\) 的系数。(存在特殊情况,一些该类型的儿子不能作为 \(t\) 个点之一,只能划归为 x 的连通块,简单讨论即可)
容易发现三种转移均为 \(O(1)\) 。
于是一轮 dp 的复杂度降为 \(O(n)\),总复杂度 \(O(n^2)\) 。
继续观察题目性质。
设一个方案的子图中有 \(t\) 个点,那么每个点对应连通块块大小为 \(\lfloor \frac{n}{t}\rfloor\) 或 \(\lceil \frac{n}{t}\rceil\) 。
于是可能的联通块大小的上下界只有 \(O(\sqrt n)\) 种,粗略估计复杂度降为 \(O(n\sqrt n)\) 。
实现后发现依然有一些冗余,简单剪肢后,实际在官方数据上的表现远好于 \(O(n\sqrt n)\) 。
[省选联考 2023] 人员调度
一眼可以看出该题是个大型贪心。
考虑暴力贪心,从叶子向根合并初始部门在该岗位的员工,每次考虑将岗位为当前节点 \(x\) 的员工加入。若子树仍有空位则直接加入;否则弹出一个价值最小的,然后加入。
直接用 set 启发式合并就行,复杂度大概为 \(O(mn\log^2 n)\) 。
考虑得到一个特解后(该特解可为空),加入一个员工,怎么得到新的最优解。
我们对于一个子树,记录出所有初始部门在该子树内且仍未弹出的员工数量,记为 \(cnt_x\);该子树大小为 \(sz_x\) 。
对于新加入的一个员工,设其初始部门为 \(u\) ,我们考虑 \(u\) 到根这一条链上每个点对应的子树 \(cnt\) 与 \(sz\) 的关系:
- 若这条链上不存在子树满足 \(cnt = sz\) ,则说明对于新员工来说,部门仍有空余,直接加入然后更新贡献即可;
- 否则一定会产生竞争,我们找到这条链上深度最深的满足 \(cnt = sz\) 的结点 \(y\) ,则竞争一定在 \(y\) 子树内进行,\(y\) 子树外的元素无法对内部竞争产生影响。我们弹出 \(y\) 子树内价值最小的结点,将新员工加入即可。容易证明该情况下一定能够为新员工调整出一个可行的空位。
上述过程可以用 树剖+线段树 无脑维护。
那么对于删除操作,线段树分治一下就行了。复杂度 \(O(n\log^3 n)\) 。在 5s 的时限内轻松跑过。
可以用 LCT 啥的将树剖部分的 log 去掉,理论复杂度降为 \(O(n\log^2 n)\) 。不过没啥必要。
[省选联考 2023] 过河卒
观察到数据范围较小,可以将两个红点和一个黑点的坐标暴力的加进状态里,复杂度是正确的。
于是就是有环图博弈。
正着做 P 都做不出来(赛时惨痛教训),考虑倒着做,由已知的确定态(必胜、必败点)倒着拓扑。
一个点 x 若被一个必败点 y 更新,则 x 被确定为必胜点。同时由拓扑的性质,该必胜点 x 胜利的最小步数为第一个这样的 y 更新的步数;
一个点 x 若被一个必胜点 y 更新,则 x 可能在最后成为必败点,要尽可能输的慢,则记录这样的 y 更新的步数的最大值。若这样的点 x 所有的度数被更新完了且未成为必胜点,则确定为必败点;若这样的点 x 最后度数未被更新完,则为平局点。
复杂度 \(O(n^6)\) 。
类似的题目有: [NEERC2016]Game on Graph , Berzerk
[省选联考 2023] 填数游戏
考虑建图,对于每个 \(T_i\) ,将其中的元素之间连边。
那么,会形成若干个连通块,Bob 能使写下的树互不相同的连通块只可能是树和基环树。
树的做法
先随便找一个根作为连通块的根。 Alice 可以给每条边对应的 $S$ 边定向,Bob 可以为这棵树选一个根,和 Alice 方向相同的边的数量即为答案。Alice 要做的即为求一个确定 $S$ 边方向的方案,使得 Bob 的所有根的选择的答案最小值最大。 可以用线段树维护出当 Bob 选择线段树上某个叶子对应的点作为根时的答案。 考虑 Alice 确定边方向的贡献是什么。若一条 \(S\) 边方向向下,则子树外答案会 +1 ,即为全局 +1 ,子树 -1 ;否则 \(S\) 边方向向上,则子树内答案会 +1 ,即为子树 +1 。
若一条 \(S\) 边能匹配的对应 \(T\) 边的端点不超过 1 个,则该 \(S\) 方向的方案是固定的;否则其两种方案都可以,我们可以钦定初始时这样的边方向都向下,然后考虑翻转一些边,当一条 \(S\) 边由向下翻转到向上时,即为全局 -1 ,子树 +2 。
那么我们令方向向下得到一个特解后,要使最小值变大,就要找到对应点到根的一条链上能够翻转的边,并将其翻转。贪心地,我们翻转能翻转的边中最浅的一条。
这样执行若干轮,将每轮的结果取 max 即可。
由于一条边翻转后不能再翻转,所以复杂度是均摊点数 \(m\) 的。
可以用线段树 区间修改+区间覆盖 维护,复杂度 \(O(m\log m)\) 。
基环树的做法
一个联通块可以被拆分成环边的部分和树边的部分。对于树边的部分,Bob 只能使其方向由环根向外,那么 Alice 对应贪心的选即可。
对于环边,可以钦定其有两个方向 A 和 B 。
若一条 \(T\) 边对应的 \(S\) 边只能匹配不超过 1 个端点,那么一定贪心地选择能匹配的,确定性地划分到 A 集合或 B 集合其中一个。
否则,这样的 \(S\) 边可以选择朝向 A 或 B 方向中任意一种,记为 C 集合。
Bob 很聪明,那么 Alice 必然要贪心地将 C 集合中的边分配到 A 和 B 集合中去,使得 min{|A|,|B|} 最大,尽可能使 |A| 和 |B| 均等即可。
答案就是 min{|A|,|B|} 。
复杂度 \(O(m)\) 。
最终复杂度 \(O(m\log m)\) 。

浙公网安备 33010602011771号