BSOJ6441题解

考虑哨卡将村庄分成了若干段,对每一段分别考虑。

我们先定义这个 swap 是有方向的,代价由我们制定的一个人来承担。

对于段内,将村庄分为三类:要去左边的段,要去右边的段,要留在这里。

在开始“正式移动”之前,我们可以对段内元素随意地移动,这样是不会有代价的。

将要去左边的村庄排在最左边,留在这里的排在中间,要去右边的村庄排在最右边。并且将每一类村庄都按照 \(p\) 从小到大排好序。

考虑留在中间的会造成的贡献。我们将这些元素的贡献给别人承担,这些元素对答案就没有贡献了。

对于别的元素,考虑两个会相交的元素,贡献明显是 \(1\)。(你可以认为每个元素都相当于在每个段的端点上)

考虑正难则反,用总代价减去不可能出现的代价。这些代价一定是段内对段内造成的贡献。

再考虑正难则反,考虑每次撤掉哨卡。每次考虑怎么合并两个段。

相当于对两个段要去的目标统计一个类似二维偏序的东西。

可以每次线段树+启发式合并 \(O(n\log^2n)\),也可以直接线段树合并 \(O(n\log n)\)

posted @ 2022-04-02 09:29  Prean  阅读(19)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};