CSP-S 2025 题解
咕了太久太久,都要考 NOIP 了才来补。
A P14361 [CSP-S 2025] 社团招新 / club
\(2\mid n,{n\over2}\) 的限制是关键,我们先把每个人贪心分给使 ta 满意度最大的集合,再看有无集合大小 \(>{n\over2}\) 来反悔贪心。
由鸽巢原理,最多一个集合超载;且把超载部分按变化量贪心分给其他集合不会导致新的超载。
最终方案的最优性考虑调整法,但我不太会严谨证明。
B P14362 [CSP-S 2025] 道路修复 / road
\(k\leq10\),且也许能规约至斯坦纳树,所以考虑 \(2^k\) 状压枚举使用的额外点。
\(n<<m\),启发我们先跑 Kruskal,只保留 MST 的边。对每个额外点的边也排序,这样可以在状压(从小到大枚举集合)时拆 \(lowbit\) 归并得到边集。边集还是太大,状压时也只保留 MST 中的边即可。时间大概是 \(O(2^kn)\)。
也可以提前排序(而不是归并)。
C P14363 [CSP-S 2025] 谐音替换 / replace
先判掉 \(|t_{j,1}|\neq|t_{j,2}|\)。
学 DS 学的:建两个 ACAM,每个颜色在两棵 fail 树上各有一个坐标,每次询问两条直链,问其点集的交的大小。差分为根链,DFS 扫一维,另一维用 BIT 维护(我是用分块卡过民间数据的,因为 \(L>>n\))。
思考:二维数点的限制是“且”,字符串匹配的限制也是“且”,能不能把变化前后的串拼起来做字符串匹配,变成一维问题?
好做法:\(s_{i,1}=s_{i,2}\) 的 \(i\) 不管。先对 \(s_1,s_2\)、\(t_1,t_2\) 找极长相同前后缀,那 \(s\) 能替换 \(t\) 当且仅当中间那段变化前后分别重合,且左右两段各自匹配,并且仅此一种方案(位置)。那我们把中间那段左右加上特殊字符 #,内部把变化先后的串拼接在一起,用 ACAM 做多模式串匹配即可。
D P14364 [CSP-S 2025] 员工招聘 / employ
不太懂“提前钦定”等 trick 的含义。对于自己的理解,搬一句昨天写的总结:提前 / 延迟钦定(处理限制)、提前 / 延迟计算贡献,拼合前后两部分各自确定的信息。也就是将决策(满足限制,造成贡献)拆成先后两部分(甚至多部分,例如分层),再通过关键信息拼起来。这有点像 DS 中计算贡献的反演。
题解也是之前写的:
先固定每天的人是否被录取:\(t_i=0/1\ (i\in[1,n])\),则 \(s_i=0\to t_i=0\),若 \(s_i=0\) 则该天的人一定不被录取,否则每个人(右部点)看 \(s_i=1\) 的天(左部点)有一个分界线(单调性)。
我们设 \(f_{i,j,k}\) 表示前 \(i\) 天(左部点),有 \(j\) 个 \(t=0\),有 \(k\) 组完整匹配的方案数(\(s=0\) 的位置不视作左部点,最后乘阶乘)。在 \(j\to j+1\) 时立即处理所有 \(c=j+1\) 的右部点(初值处理 \(c=0\),最终还要转移剩下的右部点),枚举这些右部点中选了几个向前匹配(剩下的向后匹配)即可。时间复杂度 \(O(n^3)\)。
这样设状态、转移的好处:将填 \(t_i\) 的过程融进 DP 的阶段(有点像 DP 套 DP);因为不确定性无法直接对所有点排序,但这样“动态地实现了排序过程”。
2025.11.19
浙公网安备 33010602011771号