扫描线 + 线段树.
特判序列已经有序的情况,此时不需要进行任何交换.
首先,我们可以首先进行特殊的交换,再进行一般的交换,这样显然不会使答案变劣.
特殊交换之后,还需要的次数就是当前逆序对的数目.所以特殊交换要减少尽可能多的逆序对.
考虑交换两个数 $h_x,h_y,x<y$ ,显然当 $h_x>h_y$ 时,逆序对会减少,否则会增加,于是只考虑 $h_x>h_y$ 的情况.
容易发现交换后减少的逆序对数目就是 $1+2|S|,S=\lbrace k|x<k<y,h_y<h_k<h_x \rbrace$ .
考虑左端点 $x$ 的选择,若 $h_{x_1}>h_{x_2},x_1<x_2$ , $x_2$ 就没用了.于是可以维护出有用的 $x$ .
考虑右端点 $pos_y$ 的选择,若 $h_{y_1}<h_{y_2},y_1>y_2$ , $y_2$ 就没用了.于是可以维护出有用的 $y$ .
考虑一个位置 $k$ 会存在哪些点对 $(x,y)$ 满足 $x<k<y,h_y<h_k<h_x$ .在第一个单调栈中二分找出最小的 $l$ ,使得 $h_l>h_k$ ,在第二个单调栈中二分找出最小的 $r$ ,使得 $h_r<h_x$ .
那么点对 $(x,y)$ 满足 $x<k<y,h_y<h_k<h_x$ ,即 $k$ 对 $(x,y)$ 有贡献的条件是 $x\in [l,k-1],y\in[k+1,r]$ .
这相当于是一个矩形覆盖,问题转化为给了若干个矩形,求一个点最多被覆盖了几次.
扫描线 + 线段树解决,时间复杂度 $O(n\log n)$ .
1 |
|