逆序对定义:对一个序列a[n],若i<j且a[i]>a[j],则a[i]与a[j]为逆序对。
如:序列 3, 2, 1 的逆序对数为2+1=3。
# include <bits/stdc++.h>
using namespace std;
TYPE array[ARRAYSIZE]; // 下标1~length
int length; // array[]中使用的元素个数
注:以下各算法均会改变原序列
冒泡排序求解
逆序对数即冒泡排序中交换的次数。
平均时间复杂度:O(n^2)
long long calc_BS(TYPE a[], int n) {
long long cnt = 0; bool f = true;
for (int i = 1; i < n; i ++) {
for (int j = 1; j <= n-i; j ++) if (a[j] > a[j+1])
swap(a[j], a[j+1]), cnt ++, f = false;
if (f) break;
}
return cnt;
}
// main
long long ans = calc_BS(array, length);
归并排序求解
递归对左右两半排序时,可把左右两半各自内部的逆序对数作为子问题计算。
平均时间复杂度:O(nlogn)
TYPE t[ARRAYSIZE]; // 临时数组
long long calc_MS(TYPE a[], int l, int r) {
if (l >= r) return 0;
if (r - l == 1) {
if (a[l] > a[r]) { swap(a[l], a[r]); return 1;}
else return 0;
}
long long cnt = 0;
int m = (l+r)>>1;
cnt += calc_MS(a, l, m) + calc_MS(a, m+1, r);
int p1 = l, p2 = m+1;
for (int i = l; i <= r; i ++) {
if (p1 > m) t[i] = a[p2 ++];
else if (p2 <= r && a[p1] > a[p2]) t[i] = a[p2 ++], cnt += m+1 - p1;
else t[i] = a[p1 ++];
}
for (int i = l; i <= r; i ++) a[i] = t[i];
return cnt;
}
// main
long long ans = calc_MS(array, 1, length);