原题目:
猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。
最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 a_i>a_ja 且
i<ji<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数>序列中逆序对的数目。输入格式 第一行,一个数 n,表示序列中有 n个数。
第二行 nn 个数,表示给定的序列。序列中每个数字不超过 10^910 9 。
输出格式 输出序列中逆序对的数目。
样例:
输入
6
5 4 2 6 3 1
输出
11
我先来介绍一下归并排序
时间复杂度:
O(n log n)
空间复杂度:
O(n)
定义:
归并排序是建立在归并操作上的一种有效的排序算法,该算法采用的是分治法(二分法)。
设n为序列元素的个数,a[i]为其中第i个元素,msort为归并排序的函数名,b[i]为两个相邻的子序列合并完的临时有序序列
1.将一个序列进行二分,直到分解成n个元素(l == r)
如代码:
int mid = (l + r) / 2;//取中间
if(l == r)//若l == r了,就代表这个子序列就只剩1个元素了,需要返回
{
return;
}
else
{
msort(l, mid);//分成l和中间一段,中间 + 1和r一段(二分)
msort(mid + 1, r);
}
2.将已有序的子序列合并(二分到最后的时候,一个元素一定是有序的),得到完全有序的序列
如代码:
int i = l;//i从l开始,到mid,因为现在排序的是l ~ r的区间且要二分合并
int j = mid + 1;//j从mid + 1开始,到r原因同上
int t = l;//数组b的下标,数组b存的是l ~ r区间排完序的值
while(i <= mid && j <= r)//同上i,j的解释
{
if(a[i] > a[j])//如果前面的元素比后面大(l ~ mid中的元素 > mid + 1 ~ r中的元素)(逆序对出现!!!)
{