LOJ#535「LibreOJ Round #6」花火 题解
2022/7/27 23:23:17
本文主要是介绍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/。
这篇关于LOJ#535「LibreOJ Round #6」花火 题解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南