BSOJ6441题解
考虑哨卡将村庄分成了若干段,对每一段分别考虑。
我们先定义这个 swap 是有方向的,代价由我们制定的一个人来承担。
对于段内,将村庄分为三类:要去左边的段,要去右边的段,要留在这里。
在开始“正式移动”之前,我们可以对段内元素随意地移动,这样是不会有代价的。
将要去左边的村庄排在最左边,留在这里的排在中间,要去右边的村庄排在最右边。并且将每一类村庄都按照 \(p\) 从小到大排好序。
考虑留在中间的会造成的贡献。我们将这些元素的贡献给别人承担,这些元素对答案就没有贡献了。
对于别的元素,考虑两个会相交的元素,贡献明显是 \(1\)。(你可以认为每个元素都相当于在每个段的端点上)
考虑正难则反,用总代价减去不可能出现的代价。这些代价一定是段内对段内造成的贡献。
再考虑正难则反,考虑每次撤掉哨卡。每次考虑怎么合并两个段。
相当于对两个段要去的目标统计一个类似二维偏序的东西。
可以每次线段树+启发式合并 \(O(n\log^2n)\),也可以直接线段树合并 \(O(n\log n)\)。