CF1718D 题解

ka 中的空位数量。

首先咱们转化这个“相似”的条件,发现它其实是说,笛卡尔树的结构相同。

那么我们把p建笛卡尔树然后把a的数往上填。如果此时有上面小于下面就挂了(挂了:即每个询问答案都是NO)

然后对于中间的空,它需要 > 下面的最大值,并且 < 上面的最小值。设点 i 的这个区间为 [li,ri]

接下来我们发现,我们只需要把集合 S 中的数和 d 填到这些空里满足 [li,ri] 的限制即可。

为啥:

对于一条连续的空(中间没有确定值),此时它们的区间限制都相同,那就可以任意交换位置。因此只要排序后从下往上填,一定可以满足笛卡尔树上大下小的性质,并且和区间限制不冲突。

如果中间有确定值,那因为这个值的"分隔"作用,上面的区间的 l 肯定大于下面的区间的 r。此时如果区间条件被满足了,上面一定大于下面。

那接下来就变成了一个二分图匹配问题:一边是 k 个区间,一边是 k 个点。一个区间可以匹配区间内的所有点。给定 k 个点中的 k1 个,问剩下的那个点 d 在哪些位置能使二分图有完美匹配。

“哪些位置”,结合手玩,一个初步的猜测是一段前缀/后缀,但是自己造数据手玩,发现不一定。但是手玩又发现,好像合法的 d 都是一段区间。这确实是对的。

假设现在有一个 d0 满足 d0 是一个合法位置。我们考虑此时的完美匹配,一定包含了 d0

考虑从 d0 开始走二分图的“交错路”:走一个匹配边,然后一个不匹配边,然后一个匹配边,然后一个不匹配边... 走偶数次。如果能走到 d1,那么将途经的匹配边删去,并把不匹配边匹配上,它依然是一个合法匹配且匹配数不变。那么它就变成了一个包含 d1 的完美匹配。从而此时的 d1 也是一个合法的 d

由于这张二分图的性质,显然,经过“交错路”可以走到的点一定是一段区间。从而答案是一段区间,求出区间的 l,r 即可判断了。

尽管它确实是一段区间,但我们暂时没什么办法搞出这个 l,r。总之,我们有必要先想一个问题:假设我们已知所有的点,如何求完美匹配呢?显然不能暴力Dinic,存在一个贪心做法:将点从小到大排序,每个点选择包含它的 r 最小的区间匹配。将区间按 l 排序后,相当于取一段前缀(由于点不断变大,这段前缀也是不断变大的)里 r 最小的并删除。用 pq 维护即可。

我原本想了一个用线段树单点修改区间求min+二分大力维护的做法。显然我是sb。

这个贪心确实是对的,但它的问题在于扩展性不好。点中有一个变成了未知的点,那整个匹配都被打乱了。

我们也可以用这个做法求出 k1 个点的匹配,然后剩下的那个区间是 d 的一段可行区间。但这不一定是 d 的整个可行区间,它可能只是一段子段

求出这个可行区间之后,在可行区间的左右分别二分好像是对的。虽然区间不能直接二分,但我们知道了区间中的一段,那么在这一段的左边一定是一段后缀满足,右边一定是一段前缀满足。

但这个做法是 log2 的,并且实现起来好像比较复杂,也许可以试试。

这里还有另一个做法就是,我先默认把 d 匹配到这里剩下的区间里,然后DFS走交错路,看能到哪些点。但是注意到左到右是区间连边,因此需要线段树优化建图。这就是我一开始写的做法。它 确实 是一个 log,但是它常数巨大且巨难写。

你也许会想到一个错误的贪心:按 l 排序,每次取区间内最小的点。

它为什么不对呢?这个贪心只便宜了 l,如果下一个区间的 r 突然变小,那我们上一次取不太小的点,把最小的点留给这个区间,也许是更优的。

反例:区间 [1,4],[2,3],点 3,4。这个做法会把 3[1,4],然后 [2,3] 就没有匹配了。

我们发现它的扩展性很好(如果是对的),我们可以先对 k1 个点做贪心。如果贪心的过程中区间里没有点了,就说明这个区间应该和 d 匹配。

它怎么改成对的呢?事实上按 r 从小到大排序就行了。可以证明,如果二分图存在完美匹配,那用这个办法一定可以取到一个。(证明思路就是假设当前如果取的不是区间里最小的,而是在后面取了这个最小的,这样有匹配,那么现在取最小的后面取大的那个也是可以的,不断这样交换就可以证明,如果存在一个完美匹配,一定可以用这种办法取到其中一个)

用这个策略不断的取,直到遍历当前区间时,区间里没点了,此时 d 就一定在这个区间里面了。由于我们是按 r 排序的,容易发现,此时这个区间的 r 就是最大的 d 。(很容易反证:如果 d 大于当前区间的 r 一定不行)。

一个值得注意的细节是,上述贪心过程中只能失配一次,这一次恰好用来确定 d;如果失配了两次或以上,说明无解。

对称的,我们发现按 l 从大到小排序每次取区间里最大的也是对的。这样取一遍,区间里没点的时候,这个区间的 l 就是最小的 d

然后这样就得到了合法的 d 的最大最小值,每次判给定的 d 是否在该区间里就行。注意中途做的时候判一下无解。

两次贪心用set即可简单维护,复杂度是小常数一个 log

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