LOJ#535「LibreOJ Round #6」花火 题解


题面

如果只能交换相邻两项,那么答案就是排列的逆序对数。

现在我们就是要求交换两个数,使得交换后的排列逆序对数最少。

不难发现我们一定不会交换满足 /(i<j,h_i<h_j/) 的 /((i,j)/),因为这样只会让逆序对变多。

考虑怎么刻画减少的逆序对:

  • /((i,j)/);
  • 满足 /(i<k<j,h_k<h_i/) 的 /((i,k)/);
  • 满足 /(i<k<j,h_k>h_j/) 的 /((k,j)/)。

如果我们把每一个位置看出一个二维平面上的点 /((i,h_i)/),那么后两类减少的逆序对就可以很好地被刻画为 $2/times $ 以 /((i,h_i)/) 为左上角、/((j,h_j)/) 为右下角的矩形内部(不算边界)的点的数量。

所以我们就要找到一个包含点数最多的矩形。

容易想到被另一个矩形包含的矩形一定不优,也就是说我们的左上角只会选择满足 /(h_i=/max/limits_{a=1}^i h_a/) 的 /((i,h_i)/)(设所有满足该条件的点组成的集合为 /(L/))、右下角只会选择满足 /(h_j=/min/limits_{b=j}^n h_b/) 的 /((j,h_j)/)(设所有满足该条件的点组成的集合为 /(R/)),这个可以 /(O(n)/) 直接求出。

发现这样似乎还是不太好做,考虑换一种想法:求覆盖一个点的点数最多的矩形。

由于 /(L/) 和 /(R/) 中的 /(h/) 随着 /(i/) 的增大而增大,那么对于一个点 /((k,h_k)/),我们可以二分找到 /(L/) 集合中第一个纵坐标 /(>h_k/) 的点 /((l,h_l)/) 和 /(R/) 集合中最后一个纵坐标 /(<h_k/) 的点 /((r,h_r)/),则所有左上角的横坐标在 /([l,k-1]/) 区间内、右下角的横坐标在 /([k+1,r]/) 区间内的矩形都会覆盖这个点。

那么就可以转化成二维数点问题,扫描线即可。

代码:https://paste.ubuntu.com/p/Wz6g4Rvxzq/

原创文章,作者:jamestackk,如若转载,请注明出处:https://blog.ytso.com/277364.html

(0)
上一篇 2022年7月27日
下一篇 2022年7月27日

相关推荐

发表回复

登录后才能评论