【题目描述:】

猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

【输入格式:】

第一行,一个数n,表示序列中有n个数。

第二行n个数,表示给定的序列。

【输出格式:】

给定序列中逆序对的数目。

【算法分析:】

定义:

  对于序列a,如果i < j 且 a[i] > a[j],则称a[i]、a[j]为a序列的一组逆序对

由定义可知,一个长度为n的序列最多有n * (n - 1) / 2个逆序对,注意n的取值范围,一些情况下ans要开long long

冒泡求逆序对:

求逆序对可以用冒泡排序来做,每次交换相邻两个元素的时候逆序对的个数便增加一

冒泡排序(从小到大)其实就是通过消除逆序对来保证序列的有序性。

但是每次只找到一个逆序对效率太低,时间复杂度O(n2)

归并排序求逆序对:

还有一种稳定的排序算法:归并排序,也可以用来求逆序对的数量

假设[l, mid]区间内的元素构成集合A,[mid + 1, r]内的元素构成集合B

由于A、B集合内的数字都是已经从小到大排好了的,

所以如果A> Bj ,即这两个元素能够构成一个逆序对,

则 A[i, mid] 中的所有元素都可以和Bj构成逆序对

这样子就找到了一组一组地求逆序对的方法,时间复杂度O(nlog2n)

【代码:】

 //归并排序求逆序对
#include<iostream>
#include<cstdio>
using namespace std; const int MAXN = + ; int n, a[MAXN], tmp[MAXN];
long long ans; void Merge_sort(int l, int r) {
if(l == r) return;
int mid = (l + r) >> ;
Merge_sort(l, mid);
Merge_sort(mid + , r);
int i, j, cnt = l;
for(i = l, j = mid + ; i <= mid; i++) {
for(; a[j] < a[i] && j <= r; j++)
tmp[cnt++] = a[j], ans += mid - i + ;
tmp[cnt++] = a[i];
}
for(; j <= r; j++) tmp[cnt++] = a[j];
for(i = l; i <= r; i++) a[i] = tmp[i];
}
int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++)
scanf("%d", &a[i]);
Merge_sort(, n);
printf("%lld\n", ans);
}

【洛谷】【归并排序】P1908 逆序对的更多相关文章

  1. 洛谷P1393 动态逆序对(CDQ分治)

    传送门 题解 听别人说这是洛谷用户的双倍经验啊……然而根本没有感觉到……因为另外的那题我是用树状数组套主席树做的……而且莫名其妙感觉那种方法思路更清晰(虽然码量稍稍大了那么一点点)……感谢Candy大 ...

  2. 洛谷P3157 动态逆序对 [CQOI2011] cdq分治

    正解:cdq分治 解题报告: 传送门! 长得有点像双倍经验还麻油仔细看先放上来QwQ! 这题首先想到的就直接做逆序对,然后记录每个点的贡献,删去就减掉就好 但是仔细一想会发现布星啊,如果有一对逆序对的 ...

  3. 洛谷P2513 [HAOI2009]逆序对数列

    P2513 [HAOI2009]逆序对数列 题目描述 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易 ...

  4. 洛谷P1521 求逆序对 题解

    题意: 求1到n的全排列中有m对逆序对的方案数. 思路: 1.f[i][j]表示1到i的全排列中有j对逆序对的方案数. 2.显然,1到i的全排列最多有(i-1)*i/2对逆序对,而对于f[i][j]来 ...

  5. 洛谷 P1521 求逆序对

    题目描述 我们说(i,j)是a1,a2,…,aN的一个逆序对当且仅当i<j且ai>a j.例如2,4,1,3,5的逆序对有3个,分别为(1,3),(2,3),(2,4).现在已知N和K,求 ...

  6. bzoj2431 || 洛谷P1521 求逆序对

    考虑一下插⼊法 n<=100n<=100n<=100 f[i][j]f[i][j]f[i][j]表⽰111~iii的全排列有j个逆序对的⽅案数 f[i][j]=Σf[i−1][j−k ...

  7. 【洛谷P2513】逆序对数列

    前缀和.滚动数组优化dp f[i][j]表示前i个数,逆序对数为j的方案数 我们知道,在第k个位置放第i个数,单步得到的逆序对数为i-k 则在前i个数,最多能产生的逆序对数为i个,最少0个,均可转移到 ...

  8. 洛谷P1908 逆序对【递归】

    题目:https://www.luogu.org/problemnew/show/P1908 题意:给定一个数组,求逆序对个数. 思路: 是一个很经典的题目了.通过归并排序可以求逆序对个数. 现在有一 ...

  9. 洛谷P1908 逆序对

    P1908 逆序对 2.2K通过 4.4K提交 题目提供者该用户不存在 标签云端 难度普及/提高- 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 归并排序党注意了!数组要开… ...

随机推荐

  1. [PHP] 超全局变量$_FILES上传文件

    1.$_FILES --超全局变量,HTTP 文件上传变量 通过 HTTP POST 方式上传到当前脚本的项目的数组,PHP 能够接受任何来自符合 RFC-1867 标准的浏览器上传的文件, 上传的过 ...

  2. 悟空模式-java-抽象工厂模式

    [一朝,王母娘娘设宴,大开宝阁,瑶池中做蟠桃胜会] 有一天,王母娘娘要在瑶池办party,就需要准备大量的食材.要知道,天上的神仙也分三六九等,九曜星.五方将.二十八宿.四大天王.十二元辰.五方五老. ...

  3. CPU执行程序的原理(简化过程)

    前言 看了网上的一些描述CPU执行程序的过程,发现他们涉及到的内容太多了,恨不能把整个CPU的底层结构都拿出来说,这对计算机理论知识匮乏的新人甚至是一些老人都是非常不友好的.这个问题也是当初拦在我面前 ...

  4. python__new__与__init__的区别

    __new__ __init__区别 1 class A(object): 2 def __init__(self,*args, **kwargs): 3 print "init A&quo ...

  5. IBM V7000错误代码及解决

    https://www.ibm.com/support/knowledgecenter/zh/ST3FR7_7.7.1/com.ibm.storwize.v7000.771.doc/svc_error ...

  6. h5笔记

    标签 更语义化标签 header标签 nav标签 section标签 article标签 aside标签 widget标签 footer标签 为什么要有语义化标签 能够便于开发者阅读和写出更优雅的代码 ...

  7. Android获取SD卡路径及SDCard内存的方法

    这篇文章主要介绍了Android获取SD卡路径及SDCard内存的方法,较为详细的分析了Android针对SD卡操作所涉及的类及其具体函数功能,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了A ...

  8. ida不错的插件记录

    IDASkins 地址 https://github.com/zyantific/IDASkins 作用 ida黑色皮肤插件 IDAFuzzy 地址 https://github.com/Ga-ryo ...

  9. Python redis交互

    1.首先安装模块 pip3 install redis 2.代码模板如下: from redis import StrictRedis if __name__ == '__main__': # 设置连 ...

  10. 利用 NGINX 最大化 Python 性能,第二部分:负载均衡和监控

    [编者按]本文主要介绍 NGINX 的主要功能以及如何通过 Nginx 优化 Python 应用性能.本文系国内 ITOM 管理平台 OneAPM 编译呈现. 本文上一篇系: 利用 NGINX 最大化 ...