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\) 不是关键点,则有如下转移:

\[f_{u,i}=(i+1)\prod_{s\in Son_u} f_{s,i} \]

若 \(u\) 是关键点,考虑分类:
若 \(u\) 染本身的颜色:

\[\prod_{s\in Son_u} f_{s,i+1} \]

若 \(u\) 不染本身的颜色,考虑使用总方案数减去不合法方案数:
总方案数:

\[(i+1)\prod_{s\in Son_u}f_{s,i+1} \]

不合法方案,分成两类:

  1. 儿子子树中没有该颜色;
  2. 仅有一个儿子子树中有该颜色;

\[(i+1)\prod _{s\in Son_u}f_{s,i}+(i+1)\sum_{s\in Son_u}(f_{s,i+1}-f_{s,i})\prod_{t\in Son_u,t\ne s}f_{t,i} \]

合并起来就是两种转移:
若 \(u\) 为非关键点:

\[f_{u,i}=(i+1)\prod_{s\in Son_u} f_{s,i} \]

若 \(u\) 为关键点:

\[f_{u,i}=\prod_{s\in Son_u} f_{s,i+1}+(i+1)(\prod_{s\in Son_u}f_{s,i+1}-\prod _{s\in Son_u}f_{s,i}-\sum_{s\in Son_u}(f_{s,i+1}-f_{s,i})\prod_{t\in Son_u,t\ne s}f_{t,i}) \]

上面的算法时间复杂度为 \(O(nk)\).

我们需要将上面的算法进行优化:
考虑一个没有关键点的极大子树,则其状态为:

\[f_{u,i}=(i+1)^{siz_u} \]

这件事情启示我们可以对部分状态进行合并.

显然,对于 \(u\) 为非关键点的状态,有如下处理:

\[f_{u,i}=(i+1)\prod_{s\in Son_u} f_{s,i}=(i+1)\prod_{s\in Son_u}(i+1) \prod _{t\in Son_s}f_{t,i} \]

上面的式子带来的启示是,我们可以直接处理子树内极大的包含关键点的子树.
形式化地,考虑子树 \(u\) 的内部的关键点,\(v_1,v_2,v_3\dots v_c\) 子树中所有没有关键点祖先节点的节点集合.
那么,对于 \(u\) 有如下转移:

\[f_{u,i}=(i+1)^{siz_u-\sum siz_{c_i}}\prod _{v} f_{v,i} \]

上面的过程启示我们建立一棵辅助树:
包含所有的关键点,以及所有关键点的那些子树中包含关键点的儿子.
这样的辅助树的节点数量少于 \(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\) 个数,这里使用 算数-平方 平均值不等式:

\[\sqrt{siz_{v_1}}+\sqrt{siz_{v_2}}+\dots \sqrt{siz_{v_k}}\le k\sqrt{\frac{siz_{v_1}+siz_{v_2}\dots siz_{v_k}}{k}}\le \sqrt{nk} \]

合并状态之后,按照式子进行模拟即可.
需要预处理 \((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)\).

原题

  1. #1173. 知识就是……
  2. #17855. 交叉连接
  3. [OOI 2026] Tasks from Sasha
  4. [ICPC 2018 Jakarta R] Rotating Gears
posted @ 2026-09-05 15:27  Zhou_Lemon  阅读(20)  评论(0)    收藏  举报