【考后总结】NOI 统一省选 2023

Page Views Count

文化课补完了,但是考试考炸了,所以来补题。

D1T1 火车站 station#

实际上只需要判断从 x 能否一直向一个方向移动且每个位置能不能作为这个方向的终点站。

区间覆盖差分一下即可。

提交记录:Submission - QOJ

D1T2 城市建造 cities#

一个连通块中只能有一个点被选中。

由于连通块大小是 n/cntn/cnt,只有 O(n) 种,可以枚举连通块大小。

考虑树上怎么做,假设当前枚举的连通块大小 siz,可能的连通块个数 cnt,那么有 cnt 个节点被选中,且断边后断成了 cnt 个连通块,也就是 cnt 个节点有 cnt1 条边,因此合法方案实际上是一棵树(这个性质在考场上认为是菊花或是链之类的,没拿到部分分)。

考虑一个树形 DP,设 fvv 与父亲的连边被断开,即 v 子树内部划分成大小为 sizsiz+1 的连通块的方案数。

一棵树的性质同样揭示了另一个事实:如果 v 与父亲的连边不断开,那么 v 一定是整体并入其父亲所在连通块的,也就只和子树大小 sizv 有关了。

这样对于 u 的儿子 v,不同的 sizv 直接对应不同的处理方式:

  • sizv>siz,不可能与 u 在同一连通块,(u,v) 必须断开。

  • sizv=siz,既可能与 u 在同一连通块,也可能单独成连通块。

  • sizv<siz,一定与 u 在同一连通块。

这样我们只需要统计第一种情况是否内部划分都合法,第三种情况之和与 u 拼在一起是否合法,同时将的第一种情况的方案数累成即为答案。还有一同时情况为:不存在小于 siz 的,此时若 siz=1 或存在等于 siz 的子树 v 才合法,且方案数乘上满足条件的 v 的个数(如果 u 单独成块也合法也要计入)。

这样在每个节点统计答案,默认其父亲及其他子树都不断开。


放到图上,由于删去选中节点的全部连边后不连通,容易想到点双连通分量,这样一个点双内如果选取超过一个且有没有选取的,无法达到不连通的条件。因此一个点双要么全不选,要么全选,要么选一个。反映到圆方树上就是选取点击构成的树,叶子节点一定全是圆点。

根据这个性质同样可以讨论圆点方点后 DP,fu 定义相同。

对于圆点,和上面树的情况讨论是一致的;对于方点,如果断开了其与父亲的连边,那么意味着其与儿子连边要么不断开要么全部断开,因此在对方点 DP 时,只需要考虑全部断开是否合法即可。

要注意的是,图上和树上不同之处在于即便 sizv=siz,断开 (u,v) 后不一点合法,因为这代表着 v 对应所有圆点连边都将断开,而不是像树上作为一个整体。

这样大致就是全部算法流程,还存在的问题是枚举到 n/cnt 时有可能存在方案至划分成了大小为 n/cnt 的连通块,这样会算重。可以容斥,减去 n/cnt 对应 k=0 的情况。


由于复杂度一定拉满,需要大面积卡常:

  • 只在重心位置统计答案,重心一定会被选中,否则被选中的部分是其一个子树,大小不超过一半,也就和其余部分大小相差 1 以上。

  • DFS 时按照 DFS 序重标号,O(n) 次 DFS 使用非递归 DFS。

  • 使用邻接表而不是 vector

  • 如果存在大小大于 siz 的子树内部不合法或是大小小于 siz 的子树大小之和超过了 siz,一定没有合法方案,可以不再枚举子树。

  • 如果 sizu<siz,一定没有合法方案,这一处能带来极大的优化。

提交记录(不卡常,易读):Submission - QOJ

提交记录(卡常,不易读):Submission - QOJ

D1T3 人员调度 transfer#

先考虑静态的情况。

可以看做一个二分图,左部点是职员,右部点是部门,职员到部分连带权边,要求一个最大权匹配(注意只要求权值最大)。

这样可以看做是费用流模型,每次增广最长路,直到增广路权值为负。起初增广的一定是权值较大的,后面退流时因为保证增广路权值非负,所以不会把先增广的退流。换言之,贪心地加入权值更大的直到不能加一定是正确的。

这样就摆脱了权值的限制,变成一个二分图匹配,选择一些职员,判断他们可以完全匹配就利用 Hall 定理,放在本题就是每个节点子树选择的职员总数不超过子树大小。

需要支持无序加入职员,我们需要维护数据结构,支持判断子树是否填满,以及查询最小值。

两棵线段树,一棵维护子树是否填满,维护信息 sizucntu 表示剩余空位置,这样在 u 节点加入一个元素时判断是否填满只需要查询 (1,u) 路径上的值是否都为正,如果都为正可以直接加入,否则在深度最大的被填满的节点对应子树内找到最小权值,如果当前加入的权值更大,则删除最小权值对应元素加入当前元素。子树最小权值用另一棵线段树维护,在叶子节点挂 multiset。找到深度最大的被填满的节点等价于找根链上 sizucntu 最小且 DFS 序最大的一个。

带修改可以套一个线段树分治,总复杂度 Θ((n+m)log2nlogm)

提交记录:Submission - QOJ

D2T1 过河卒 zu#

不是博弈论,是博弈论暴搜。

图很小,可以压成 106 的状态记录三个棋子的位置,合法转移直接连边。

不好解决的问题是可能出现平局——成环,这样不能从起始状态开始搜。改成从每个结束状态开始搜,由于根据步数的奇偶性可以判断出当前是谁的回合,我们只需要拓扑转移即可。

如果一个状态当前被转移到的都是必败状态,那么一直取步数的 max,一旦出现必胜决策可以直接入队,由于 BFS,此时步数一定最小,且在当前位置决策者一定会选这种必胜决策。也就是魔改了一下拓扑排序。

在答案处要注意的是,如果是必败状态且初始状态处于一个环中,那么会选择走环来达到不败的情况,要特判一下。(在转移过程中由于没有被完全剥出的节点不会入队,实际上也是存在不败一定选不败)

提交记录:Submission - QOJ

没有想到的是如何处理平局以及压成状态建图搜索的简单转换。

该问题针对环的处理是:如果走出环是必胜,那么忽略环直接入队,否则就是平局。


差不多的题:AtCoder-ABC261_Ex Game on Graph

不用压状态了,但是要区分走到这个节点是谁的回合,可以把点拆开,建反图之类的的操作和上面类似。

有边权,所以后手一定是类似拓扑排序地所有点的值取 max 才入队,否则会选择平局;先手则是取 min,但是不能保证第一次更新就是 min,而多次更新的复杂度不能保证,把队列改成堆就可以了。

该问题针对环的处理是:先手(希望更小)一定走出环,直接入队,后手(希望更大)一定尽量走环,也就是要所有入边都处理完再入队。

D2T2 填数游戏 game#

完全想反了呀!!!树的情况完全不会做呀!!!

似乎是逐步分析特殊性质得到正解的典型题,几乎是复述了 ZCPB 的题解

对于 Alice 的方案,Bob 会选择相同数最小的一个,Alice 会最大化相同数的最小值,或是最小化不同数的最大值。

性质 A#

只需要判断是否合法。

二元关系考虑连边,对于每个连通块,如果 |E|>|V| 则不合法。

(我为啥考场上写的二分图匹配?)

性质 B#

|E|=|V|,是环。

如果 SiTi=,那么没有贡献,如果 |SiTi|=1,那么一定选有交的一个,如果 |SiTi|=2,两个都可以选。

在环上一定要么都选左侧要么都选右侧,考虑设 cnt1,cnt2,cnt3 分别表示只能选左侧、只能选右侧和两侧都可以选的个数,那么实际上 Alice 会把 cnt3 分给 cnt1,cnt2 使得二者最小值最大,如果 cnt1+cnt3<cnt2 或是 cnt2+cnt3<cnt1,则答案是 cnt1+cnt3cnt2+cnt3,反之策略是平均分配,即 cnt1+cnt2+cnt32

基环树#

树部分的边只能选儿子一侧的,统计一下加上环部分答案即可。

性质 C#

这个性质没啥用!

性质 D#

如果是基环树同上,下面讨论如果是树,这个特殊性质是所有边都可以选双向。

树性质是找到一个节点作为根,所有边都选儿子一侧的。

考虑一条边 (u,v) 钦定选择 u 之后,u 一侧子树的所有节点如果为根,那么 (u,v) 这条边应当选择 v,所以选择 u 会使 u 一侧子树的不同数增加 1,同理使 v 一侧的相同数增加 1

定义一条边的方向为选择的一端,考虑两条相向的边,它们对相同数贡献的点集无交,如果都调转方向变成相背的边,贡献的点集是全集,而 Alice 的目的是最大化相同数最小值,所以 Alice 的构造方案一定不存在相向的边,进一步地说,Alice 的构造方案一定是选一个节点作为根,所有边都选叶子一侧的。

(其实得到这个性质就可以换根做了。)

实际上,有多少边直接或间接指向某个节点,那么这个节点就被贡献了多少次不同数,因此 Bob 会选择被指向最多的一个节点,结合上面对 Alice 方案的分析,就是 Alice 构造树深度最深的节点。

因此 Alice 目的使树高尽量小,所以会选择树的直径中点作为根,答案就是所有边数减去树高,即 n1d2d 是直径。

#

容易想到的是把两个端点都能选的边权值设为 1,其余设为 0,跑一个带权直径处理。

但是还有一些只能选一端的边是钦定了的,这些也要考虑在内。其实就是性质 C 的做法,给指向子树内增加 1,差分做一下就行。

然后大致也是找到一个节点为根,所有两端都能选的边选择儿子一侧,Bob 会选择点权(也就是被贡献不同数)加到根路径上边权之和最大的一个,Alice 目的是最小化这个最大值。所以要求一个有端点点权的带权直径。会产生答案的总边数(有交的)减去直径除以二向下取整即为答案。

这个看着好像很怪,似乎会有找不到直径中点的情况,实际上仔细思考发现找不到直径中点说明一段点权很大,那么向这一端移动过程中会经过点权与这一端很接近的位置,这才是直径。也就是这种带权直径端点不一定是叶子。

提交记录:Submission - QOJ

作者:SoyTony

出处:https://www.cnblogs.com/SoyTony/p/Problems_in_NOI_Unified_Provincial_Team_Selection_2023.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   SoyTony  阅读(353)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示