难度:5
感觉难度有点虚高,这是归并排序的应用,求逆序对,因为诸如冒泡排序此类的排序,都是交换相邻的两个数,问几次交换排序能完成,就是问有多少个逆序对,而逆序对的统计可以在合并两个序列的时候顺便统计,最后需要注意一点逆序对的个数可能超过int,
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pa;
const int maxn = 5e5 + 5;
ll cnt;
void merge(int *a, int l, int mid, int r) {
int i = l, j = mid + 1;
int temp[maxn], index = 0;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) temp[index++] = a[i++];
else temp[index++] = a[j++], cnt += mid - i + 1;
}
while (i <= mid) {
temp[index++] = a[i++];
}
while (j <= r) {
temp[index++] = a[j++];
cnt += mid - i + 1;
}
for (int i = 0; i < index; i++) {
a[l + i] = temp[i];
}
}
void merge_sort(int *a, int l, int r) {
if (l < r) {
int mid = (l + r) / 2;
merge_sort(a, l, mid);
merge_sort(a, mid + 1, r);
merge(a, l, mid, r);
}
}
int main() {
int n;
while (cin >> n && n) {
cnt = 0;
int a[maxn];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
merge_sort(a, 0, n - 1);
cout << cnt << endl;
}
return 0;
}