2026年NOICA联盟-NOIP模拟赛(十四)

C. 聚拢(merge)

题目描述

有一个单调不降的序列 \(a_1,a_2,\dots,a_n\),你要将每个位置恰好操作一遍,对于位于位置 \(i\) 的一次操作,将所有小于 \(a_i\) 的位置加一,所有大于 \(a_i\) 的位置减一。

记 \(\operatorname{val}(a)\) 等于所有操作顺序中,操作完后 \(a_n-a_1\) 的最小值。

现在给你每个位置 \(i\) 的候选值集合 \(S_i\),你要统计所有单调不降序列的 \(\operatorname{val}\) 之和。

做法

先考虑对于一个序列 \(a\),怎么求 \(\operatorname{val}(a)\)。

将限制放宽,原本是将满足小于 \(a_i\) 的一个极大前缀加一,现在放宽成将一个小于 \(a_i\) 的前缀加一,但是要保证单调性。

发现全加一对差分数组的影响较小,考虑转到差分数组 \(b\) 上考虑,定义序列 \(b,b_1=0,b_i=a_i-a_{i-1}\)。那么一次操作就等价于在 \(i\) 前面任选一个不为零的位置减一,再在 \(i\) 后面任选一个不为零的位置减一。最终 \(a_n-a_1=\sum b_i\)。

现在相当于要最大化减一的次数,由于一次操作的对前面的影响和对后面的影响互不干扰,可以分别贪心。对于前面的减,可以从 \(1\) 到 \(n\) 遍历 \(b\),每次前面有非零的位置就直接减一。后面的减同理,然后把两个拼起来就得到了最优的操作。


拷了一篇题解,原因是为了方便,原作者:1795MiB

考虑放宽限制, 一次操作可以钦定两个数 \(u\) 和 \(v\) 满足 \(u \le a_x, v \ge a_x\), 让 \(a_i < u\) 的数 \(+1\), \(a_i > v\) 的数 \(-1\). 显然按这样操作最终的极差不会小于原操作.

考虑长为 \(n\) 的序列 \(b_i\) 满足 \(b_1 = 0, b_i = a_i-a_{i-1} (2 \le i \le n)\). 则操作位置 \(x\) 会使得 \([1, x]\) 内任意一个 \(>0\) 的位置 \(-1\), \([x+1, n]\) 内任意一个 \(>0\) 的位置 \(-1\) (没有则无事发生), 最终的答案为操作后 \(\sum_{i=1}^n b_i\) 的最小值, 也即操作前 \(\sum_{i=1}^n b_i\) 减去非无事发生的次数, 又即无法分配到任意一个 \(x\) 上的值的数量.

考虑操作的最终形态, 对每个位置 \(x\) 记 \(l_x\) 和 \(r_x\) 表示 \(-1\) 的位置 (没有则为 \(-\infty\) / \(\infty\)). 考虑贪心地为每个 \(x\) 分配 \(l_x\) 与 \(r_x\). 从左到右考虑 \(b_i\), 依次为 \(i \le x \le n\) 分配 \(l_x\) 为 \(i\), 再为 \(i-1 \ge x \ge 1\) 分配 \(r_x\). 显然这样能够分配到的是最多的.

考虑类似自动机地计算答案, 以更为方便地进行计数 Dp. 考虑维护目前所有 \(b_i\) 的和 \(s\), 则每次加入一个 \(b_i\) 会使 \(s \leftarrow s + b_i\). 由于当 \(s < i\) 时, \([1, i]\) 的 \(l_i\) 必然会有 \(i - s\) 个无法分配, 则不妨认为这 \(i - s\) 次无事发生事实上是有事发生, 并将 \(s \leftarrow i\). 若 \(s > n + i - 1\), 此时由于至多只有 \([1, n]\) 的 \(l_i\) 与 \([1, i-1]\) 的 \(r_i\) 能够分配, 则必然有 \(s - (n + i - 1)\) 个值无法分配到 \(l_i\) 或 \(r_i\) 上, 因此 \(ans \leftarrow ans + [s - (n + i - 1)]\), \(s \leftarrow n + i - 1\).

总结一下, 自动机的流程为 \(s \leftarrow \max(s + a_i, i)\), \(ans \leftarrow ans + s - (n + i - 1)\), \(s \leftarrow \min(s, n + i - 1)\).

设 \(f_{i, j, s}\) 表示考虑到了 \(S_i\), 值选了 \(j\), 变量 \(s\) 的值的方案数. 由于贡献完答案后还需将后面的序列补全, 需设 \(g_{i, j, s}\) 为答案, 转移完全一致并额外有 \(f \rightarrow g\) 的一个转移. 前缀和优化转移即可.

\(O(n^3)\).

D. 长链仪礼(ritual)

题目描述

有一棵以 \(1\) 为根的树,每个点有点权,还有初始颜色和目标颜色,颜色只有红蓝两种。你可以执行以下操作任意次,目的是将所有点的颜色变成目标颜色。

选定一个点 \(u\),并在 \(u\) 的子树内选一个点 \(v\),并在 \(u,v\) 路径上选两个点 \((x,y)\) 交换他们的颜色,这次操作的代价为 \(u\) 的点权。

做法

这个做法是返回贪心。

定义 \(a_u\) 等于 \(u\) 到根的路径上的点权最小值。那么操作等价于选两个有祖先后代关系的点,交换颜色,代价为离根近的点的 \(a\) 值。

对于初始颜色和目标颜色不同的点,称为关键点,定义初始颜色为红色的点为红点,初始颜色为蓝色的点为蓝点。最终就是要将两种点两两配对,交换颜色。(正确性不知道,但感性理解是对的,就是交换是二元关系,颜色相同的不需要交换,颜色不同的交换一次之后直接就可行了不会再被改变?)

最终的点对分为两种:

  1. 有祖先后代关系的:交换代价就是离根近的点的 \(a\)。

  2. 在某个点的不同子树中的:找到 LCA,交换 和 LCA 颜色不同的点 与 LCA 的颜色,然后再交换另一个点和 LCA,那么交换这两个点的代价就是 \(2\times a_{LCA}\)。

  • 对于同种的点对,LCA 离根越远显然越优。

  • 对于不同种的点对,会互相影响选择。对于 LCA 相同的,第一种点对一定比第二种优。对于 LCA 不同的,没有严格的谁更优。

有一个看起来很假而实际上也是假的贪心做法:自下而上贪心,每次能合并就直接合并,先合并第一种再合并第二种点对。

假的原因是,点 \(u\) 的某棵子树最优不一定能得到 \(u\) 的整棵子树最优。由于第一类点对优于第二类点对,有可能 \(u\) 是关键点而且 \(u\) 子树的最优解可能不会剩下异色关键点,这种情况下,可能把子树内某个第二种点对拆开,将 \(u\) 换进去更优,这样调整的代价就是 $a_u-2\times a_{\text{原本的}LCA}。

根据这个调整策略,有如下反悔贪心:从底向上贪心,先合并第一种点对,再合并第二种点对。如果当前点是关键点并且无法合并第一种点对,选择子树中代价最大的第二种点对,如果调整代价小于 \(0\),就拆开一个调整。这样需要用大根堆维护子树内代价最大的第二种点对,启发式合并的时间复杂度为 \(\mathcal O(n\log^2 n)\),听说可并堆是 \(\mathcal O(n\log n)\)。


先说一个重要限定:不是任意把异色关键点配起来都最优。正确的说法是,原问题可以化成“把所有 (1\to0) 的点与所有 (0\to1) 的点做最小费用完美匹配”;反悔贪心是在这个匹配问题上利用树形结构求最优匹配。

设

[
A_u=\min_{x\text{ 是 }u\text{ 的祖先(含 }u)} a_x.
]

1. 为什么可以化成异色关键点的两两匹配?

记

  • (+):(b_u=1,c_u=0),这个点多了一个 (1);
  • (-):(b_u=0,c_u=1),这个点缺一个 (1)。

交换不改变全树中 (1) 的总数,所以 (+) 和 (-) 的数量必须相同,否则无解。

定义两个关键点 (x,y) 的配对费用 (D(x,y)):

[
D(x,y)=
\begin{cases}
A_x,&x\text{ 是 }y\text{ 的祖先},\
A_y,&y\text{ 是 }x\text{ 的祖先},\
2A_{\operatorname{lca}(x,y)},&x,y\text{ 不可比}.
\end{cases}
]

这个费用确实能实现

  • 有祖先关系:设 (x) 是 (y) 的祖先。选根到 (x) 路径上费用最小的点作为操作起点,就能在一条合法链上直接交换 (x,y),费用是 (A_x)。
  • 没有祖先关系:令 (w=\operatorname{lca}(x,y))。先让颜色不同的端点与 (w) 交换,再让 (w) 与另一个端点交换。两次之后 (w) 恢复原色,两个端点完成配对,总费用是 (2A_w)。

因此,任意一个 (+) 与一个 (-) 都能按 (D) 的费用完成配对。

任意操作序列也不可能更便宜

把每个 (1) 想象成一个带身份的“令牌”。一次交换若涉及不同颜色,就相当于把一个 (1) 从一个端点移动到另一个端点;同色交换不改变状态,可以忽略。

一次实际移动的两个端点必然在一条祖先—后代链上。若浅端点是 (x),操作起点在 (x) 上方或等于 (x),操作费用至少是 (A_x=D(x,y))。而上述 (D) 满足三角不等式,所以一个令牌经过若干次移动,从起点到终点的总费用至少是起点、终点之间的 (D)。

于是,任何操作序列都对应着“初始为 (1) 的点”到“目标为 (1) 的点”的一种配对,其总费用不低于这组点的最小匹配费用。初始和目标中都为 (1) 的点可以互相固定;通过三角不等式的交换配对,它们不必参与最优匹配。剩下的正好是 (+) 与 (-)。

结合前面的构造可知:

原问题的最优值,等于所有 (+) 与 (-) 之间按 (D) 费用做最小权完美匹配的费用。

这也说明:异色两两配对是一个等价的优化模型,不是说任意配对都最优。


2. 如何证明反悔贪心正确?

光说“选最大的二类对”还不够;证明的关键是说明:处理某个子树时,哪些决策可以撤销,以及撤销后对更高层来说留下了什么。

记 (A_u) 为上面的根路径最小费用。沿根到叶方向,(A_u) 不增。

两类匹配

  • 一类对:两个关键点有祖先关系,费用是浅端点的 (A)。
  • 二类对:两个关键点位于某节点 (w) 的不同子树,费用是 (2A_w)。

假设正在处理节点 (u)。

引理一:一类对可以固定,不需要反悔

若一对关键点都在 (u) 的子树内且有祖先关系,它的费用至多是 (A_u):浅端点在 (u) 的子树中,路径最小值不大于 (A_u)。

如果用 (u) 的关键点替换这对中的一个点,新的直接配对费用是 (A_u),不会比原来更便宜。并且,从 (u) 子树外观察,子树内任意一个点都处于同一个“子树位置”:它与任意外部点的配对费用相同。

更形式化地,若 (u) 是 (x) 的祖先、(y,z) 在 (u) 子树外,则费用满足下面的交换不等式:

[
D(u,x)+D(y,z)\le D(u,y)+D(x,z).
]

因此,若一个一类对已经可以在子树内完成,把它留在内部不会比把两个点分别送到外面更差。一类对不需要进入反悔堆。

引理二:二类对是唯一可能值得拆开的内部匹配

假设 (u) 自己是关键点,它在子树内找不到一个尚未配对的异色点直接配对。

若拆开一个费用为 (C) 的二类对:

  • (u) 与其中颜色相反的端点直接配对,费用为 (A_u);
  • 原二类对被取消,省下 (C);
  • 另一个端点留下,作为尚未配对的需求继续向上。

所以拆开的总费用变化是

[
\Delta=A_u-C.
]

若 (C>A_u),拆开能降低费用;若 (C\le A_u),拆开不划算。

拆开不同的二类对,留下的未配对需求从更高层看来具有相同的“边界类型”:它们都还在 (u) 子树内,且留下的颜色与 (u) 相同。因此,为了让费用变化 (A_u-C) 最小,应拆费用 最大的二类对。若最大值也不超过 (A_u),就不拆。

这就是大根堆的来源。

归纳处理每个节点

处理 (u) 的子树时,维持如下结构:

  1. 已完成的匹配中,一类对可以固定;
  2. 二类对保存在堆里,表示“目前这样配好,但必要时可以撤销”;
  3. 未配对的需求保留其颜色,等待更高层处理。

合并 (u) 的儿子时,来自不同儿子子树的两个异色未配对需求,其最近公共祖先就是 (u),所以配成二类对的费用都是 (2A_u)。可以先尽量配成二类对,并把这些对放入堆;它们不是永久决定,之后可以被祖先反悔。

再处理 (u) 自己:

  • 如果有未配对的异色需求,就以 (A_u) 做一类配对;
  • 如果没有,就查看堆中费用最大的二类对。若它的费用大于 (A_u),拆开它并让 (u) 与合适端点配对;否则保留堆中所有对,让 (u) 未配对地向上。

由上面的两个引理,任何最优解都可以调整成算法这种形式:一类对不用拆;若要让 (u) 取代一个已配对的端点,只需考虑拆二类对,且拆最大者最优。因而逐个节点处理后,这个不变量继续成立。

最后回到根节点。若 (+)、(-) 数量相等,最优解应没有未配对需求;算法得到的无未配对状态费用就是最小匹配费用,也就是原问题答案。若数量不等,则前面已经说明无解。

一句话概括反悔贪心的正确性:一类对在子树内已经足够便宜,可以固定;二类对只是暂存的配对。当祖先关键点出现时,唯一可能有利的调整是拆掉一个二类对,而拆费用最大的那个最优。

posted @ 2026-10-22 08:01  Tanliu  阅读(31)  评论(0)    收藏  举报