2026.9.5 模拟赛
http://47.113.203.55/contest/6a98cbeba1cb4701d4b54c07/problems
仙人掌多校联考
项目分配
可以理解为一般图匹配.
使用神秘贪心.
考虑我们只需要求出最大匹配的方案,就能求出原问题.
将区间按照左端点排序.
维护两个小根堆 q1 与 q2,分别表示未匹配的区间与已匹配的区间,只进行维护区间的右端点.
有如下贪心策略:
- 若
q1.top()<l则表明可以进行匹配,将r加入q2. - 若
r<q2.top()则表明有更有的匹配,将q2.top()加入q1,将r加入q2. - 否则,加入
q1.
四向联结
对四面建立虚点,那么问题相当于求出 4 个虚点的最小斯坦纳树.
如果直接进行 Dijkstra 的话复杂度是 \(O(2^knm\log nm+3^k nm)\).
但是可能过不去,因此考虑对于 Dijkstra 进行优化:
发现 Dijkstra 的 \(O(nm)\) 是算法本身必定会有的枚举复杂度,因此考虑优化 \(O(\log nm)\).
这一部分的复杂度是由于数据结构所造成的,考虑使用更加优秀的数据结构:
注意到值域非常小,最终答案是 \(O(V(n+m))\) 级别的.
由计数排序的思想,我们可以开 \(V(n+m)\) 个队列进行维护.
这样 Dijkstra 时间复杂度为 \(O(nm+V(n+m))\).
这样可以轻松跑过去.
楼层任务
比较神秘的一道树上 DP 题.
设 \(f_{u,i}\) 表示节点 \(u\) 有 \(i\) 种 祖先 的颜色可以选择的方案数.
若 \(u\) 不是关键点,则有如下转移:
若 \(u\) 是关键点,考虑分类:
若 \(u\) 染本身的颜色:
若 \(u\) 不染本身的颜色,考虑使用总方案数减去不合法方案数:
总方案数:
不合法方案,分成两类:
- 儿子子树中没有该颜色;
- 仅有一个儿子子树中有该颜色;
合并起来就是两种转移:
若 \(u\) 为非关键点:
若 \(u\) 为关键点:
上面的算法时间复杂度为 \(O(nk)\).
我们需要将上面的算法进行优化:
考虑一个没有关键点的极大子树,则其状态为:
这件事情启示我们可以对部分状态进行合并.
显然,对于 \(u\) 为非关键点的状态,有如下处理:
上面的式子带来的启示是,我们可以直接处理子树内极大的包含关键点的子树.
形式化地,考虑子树 \(u\) 的内部的关键点,\(v_1,v_2,v_3\dots v_c\) 子树中所有没有关键点祖先节点的节点集合.
那么,对于 \(u\) 有如下转移:
上面的过程启示我们建立一棵辅助树:
包含所有的关键点,以及所有关键点的那些子树中包含关键点的儿子.
这样的辅助树的节点数量少于 \(2k\),能够表示上面第 1 种情况的转移.
DP 的时间复杂度为 \(O(k^2)\)
现在考虑 \(u\) 为关键点的转移:
考虑如果我们直接进行转移的话,给出一棵菊花就能将复杂度卡到 \(O(nk)\).
因此我们需要将本质相同的状态进行合并,即按照子树大小将状态进行合并.
我们惊奇地发现,\(siz_u>\sum_{s\in Son_u}siz_s\).
由于经典的结论,只有 \(O(\sqrt{siz_u})\) 种本质不同的 \(siz_t\).
(证明可以使用贪心构造等差数列可以卡满,这说明这个上界是随机数据下难以卡满)
计算总共的本质不同的 \(siz_t\) 个数,这里使用 算数-平方 平均值不等式:
合并状态之后,按照式子进行模拟即可.
需要预处理 \((i+1)^k\),这里使用光速幂,预处理复杂度为 \(O(k\sqrt{n})\),查询复杂度为 \(O(1)\).
DP 部分的时间复杂度为 \(O(k\sqrt{nk})\).
算法总时间复杂度为 \(O(n+k^2+k\sqrt{nk})\).
旋转齿轮
显然可以对于树进行黑白染色,这样就能去除取负的影响.
问题就是:
给定一棵树,单点修改点的存在性,询问连通块点的个数,连通块整体修改.
这是可以使用 Top Tree 解决的问题,但是显然我是不会的.
考虑如何刻画一个连通块:
显然,对于一个点,我们可以找到其所在连通块的深度最浅的点:
我们可以进行树剖,对于每条重链使用 set 维护点的存在性,查询时跳链即可.
由于 set 的 empty() 与 begin() 是 \(O(1)\) 的,因此这一部分时间复杂度为 \(O(\log n)\).
这时,设 \(x\) 为连通块的最浅点.
我们需要一个函数 \(c(x)\) 表示点 \(x\) 的根链上有多少不存在的点.
那么节点 \(y\) 与 \(x\) 联通的充要条件为:
\(y\in \operatorname{Subtree}_x \land c(x)=c(y)\).
将树放到 dfs 序上,可以使用线段树进行维护:
我们需要维护线段树上区间的 \(Lca\),\(c(Lca)\),\(\Delta c(x)\),\(\Delta \alpha\),\(siz\).
但且仅当子区间的 \(c(ls_{Lca}) = c(x_{Lca})\),那么 $\Delta \alpha $ 可以下传,\(siz\) 可以上传.
同时注意 \(c(Lca)\) 是会更新的.
时间复杂度为 \(O((n+q)\log n)\).
精细实现 \(Lca\) 可以做到 \(O(n+q\log n)\).

浙公网安备 33010602011771号