最近遇到求解逆序数的问题,题目如下:
问题描述:
A为一个有n个数字的有序集 (1<=n<=1e5),其中所有数字各不相同。
当存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数。
请问序列A中的逆序对有多少个。
输入
第一行,序列长度n。(1<=n<=1e5)
第二行,序列a[1]…a[n]。(a[i]<1e8)
输出
逆序对个数。
样例输入
5
5 4 3 2 1
样例输出
10
思路
直接暴力求解,时间复杂度为O(n2),算法时间复杂度较大。可以考虑分治思想,运用二路归并排序的思想,将要求解的序列分成两段序列,我们假设这两段序列有序且内部的逆序数已经求出,现在需要解决的问题是两段序列之间的逆序数。在两段序列内部设置两个变量i,j(类似于归并排序),对于前一段中每一个数字,当i指向的数字比j指向的数字大时,都有逆序数r-j+1个逆序数,循环排序并累计,最终的结果即为所求。详情见代码
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef long long ll; \\数据规模可能较大,注意开long long,
ll count(int p[],int l, int mid, int r) {
int i = l, j = mid, len = r - l +