逆序对(洛谷P1908题题解,Java语言描述)
题目要求
题目链接
分析
逆序对这个说法我们在线性代数应该就接触过了吧,这里的逆序对应该与序偶也有关吧,总之简单点说就是顺序反了(相较于我们的比较标准)的一对数据。
<1, 2, 3, 4, 5> 是一组数据,它是全部顺序无逆序的。
如果我们给出这样一组数据:<1, 3, 2, 4, 5> ,它只有 2、3 之间是反的,逆序对的数目是1。
如果我们给出这样一组数据:<1, 3, 4, 2, 5> ,它有 2、3 和 2、4 之间是反的,逆序对的数目是2。
……
那怎么去找呢?
写一个O(N2)O(N^2)O(N2)的算法吗?
题目数据被加强了,所以50W的O(N2)O(N^2)O(N2)……很恐怖
线性的算法有点扯,一般想不到,那就想一个O(NlogN)O(NlogN)O(NlogN)的吧,什么呢?
归并排序!
在每次合并的时候,要么顺序保留要么逆序交换,所以在并+交换的时候做一下统计就能得到答案。
归并排序的思想是分治法,所以本题的归类也是分治算法,建议好好体会。
关于归并排序,荐读:
- 《一文道破Sort的方方面面》
- 《排序算法大全(Java语言描述)》
- 《深夜再侃侃排序》
值得注意的是:由于数据可能达到50W,所以在Java处理的时候注意一些细节,否则可能 T爆被迫换C++ 或是 听取WA声一片:
- 使用 long 做counter的数据类型(C++要用longlong)
- 使用BufferedReader来读,读取正行;即使使用Scanner也一定不要nextInt()。不然,盲猜必炸
AC代码(Java语言描述)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Main {private static long result = 0;private static int[] nums, temp;private static void mergeSort(int left, int right) {if (left == right) {return;}int mid = (left+right)/2, i = left, j = mid+1, k = left;mergeSort(left, mid);mergeSort(j, right);while (i <= mid && j <= right) {if (nums[i] <= nums[j]) {temp[k++] = nums[i++];} else {temp[k++] = nums[j++];result += mid-i+1;}}while (i <= mid) {temp[k++] = nums[i++];}while (j <= right) {temp[k++] = nums[j++];}for (int m = left; m <= right; m++) {nums[m] = temp[m];}}public static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));int num = Integer.parseInt(reader.readLine());String[] array = reader.readLine().split("\\s+");reader.close();nums = new int[num];temp = new int[num];for (int i = 0; i < num; i++) {nums[i] = Integer.parseInt(array[i]);}mergeSort(0, num-1);System.out.println(result);}}
逆序对(洛谷P1908题题解,Java语言描述)相关推荐
- 信息学奥赛一本通 1311:【例2.5】求逆序对 | 1237:求排列的逆序数 | OpenJudge NOI 2.4 7622:求排列的逆序数 | 洛谷 P1908 逆序对
[题目链接] ybt 1311:[例2.5]求逆序对 ybt 1237:求排列的逆序数 OpenJudge NOI 2.4 7622:求排列的逆序数 洛谷 P1908 逆序对 ybt 1311,123 ...
- 线性存储的最短平均检索时间(洛谷P1253题题解,Java语言描述)
题目要求 P1253题目链接 分析 很像 ~洛谷P1223题题解~,也是一种类似SJF的贪心法. 排个序,由于两个不大于10000的数,乘起来还是int,就使用int属性吧. 数据量小,所以Scann ...
- 队列模拟约瑟夫问题(洛谷P1996题题解,Java语言描述)
题目要求 P1996题目链接 分析 以前就研究过"约瑟夫环"问题: <单循环链表求解约瑟夫环问题(Java语言描述)> <杀人游戏~约瑟夫环(洛谷P1145题题解 ...
- 枚举求解单词方阵(洛谷P1101题题解,Java语言描述)
题目要求 P1101题目链接 分析 可以用DFS做,但我立下了个Flag,所以就用了朴素的枚举来做.... 结果,我的天哪,做了好几个小时-- 其实这种地图题,真的适合 DFS or BFS or D ...
- 快速幂||取余运算【模板】(洛谷P1226题题解,Java语言描述)
题目要求 P1226题目链接 分析 标准的快速幂取模算法板子,之前这个算法我在这篇文章中讲过了:<快速幂算法详解&&快速幂取模算法详解>. 这里选择使用比较简单的API实现 ...
- 贪心策略摘果子(洛谷P1478题题解,Java语言描述)
题目要求 P1478题目链接 分析 本题的低配版题目链接 → 题解 那个题就是纯水题没啥可写的,我除了贴代码无话可说,但这题吧,虽然不算难,但也可一说. 建议大家移步这里 → 精辟题解 这位爷写了本题 ...
- 麦森数(洛谷P1045题题解,Java语言描述)
题目要求 题目链接 分析 这题挺经典的,快速幂取模算法,如果求出大数再取模就可能T掉. 之前有篇文章写了这个算法:<快速幂算法详解&&快速幂取模算法详解> 既然是Java, ...
- 求子集元素之和(洛谷P2415题题解,Java语言描述)
题目要求 P2415题目链接 分析 这题我觉得--当个数学题做就好了嘛. 有一个数N的情况:result = 1 * N 有两个数N1.N2的情况:result = 2 * (N1+N2) 有三个数N ...
- N进制正反累加判回文数(洛谷P1015题题解,Java语言描述)
题目要求 P1015题目链接 分析 开始的时候写了这么一个代码,应该是比较基础的,是十进制的. private static void low() {Scanner scanner = new Sca ...
最新文章
- 微信小程序获取用户手机号,后端php实现 (前后端完整代码附效果图)
- 二维前缀和+差分 HDU6514 Monitor
- Exploring Data with Python免费电子书
- 字段变成小写 序列化_序列化/反序列化
- C++ 随机函数----谈rand() 和 srand() 体会
- 大话设计模式之装饰模式
- 用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
- vmdk文件怎么安装到虚拟机_【技术分享】虚拟机镜像解析
- Qt IFW基本用法
- NSUserDefaults
- 虚拟机ubuntu安装ssh服务器,经过Xshell远程链接虚拟机VMVARE中的Ubuntu
- win10共享打印错误0x0000006_Win10连接共享打印机提示0x80070035错误的解决办法
- 深度学习 autoencoder_笔记:李淼博士-基于模仿学习的机器人抓取与操控
- [转载]【Java EE】Struts2.1.6与Spring2.5.6框架整合
- 不玩了?王思聪退出香蕉娱乐董事长职务,麻闻多接任
- python 可视化界面 打开excel_python如何将excel数据处理可视化
- 46. PHP 数据库
- 软件架构--架构设计的整体介绍
- 测试工程师职位要求汇总
- [转]用友NC单据UI基本代码示例