#include<cstdio> #define REP(i, a, b) for(int i = (a); i < (b); i++) using namespace std; const int MAXN = 112; int a[MAXN], n; void merge_sort(int l, int r) //Here is the left closed and right open interval, the interval does not need to add one and subtract one { if(l + 1 >= r) return; int m = (l + r) / 2; // average of l and r merge_sort(l, m); merge_sort(m, r); //First recurse, then solve int p = l, q = m, i = l, t[MAXN]; while(p < m || q < r) { if(q >= r || p < m && a[p] <= a[q]) t[i++] = a[p++]; //The right interval is empty or the left interval is not empty and a[p] is better join when else t[i++] = a[q++]; } REP(i, l, r) a[i] = t[i]; } intmain() { scanf("%d", &n); REP(i, 0, n) scanf("%d", &a[i]); merge_sort (0, n); REP(i, 0, n) printf("%d ", a[i]); puts(""); return 0; }
Inverse pairs satisfy two conditions, i < j and ai > aj
Merge can find the reverse order pair, because it is added in order, so when the right interval is added, the number in the left interval satisfies i < j, and then the number that has not been added on the left must be larger than the current a[q], it should be by size added, so it satisfies ai >aj, so at this time, the counter can add the number of the left interval that has not been added, that is, m-p. Note that the left is closed and the right is open, so m-p does not need to be added by one.
// reverse order version #include<cstdio> #define REP(i, a, b) for(int i = (a); i < (b); i++) using namespace std; const int MAXN = 112; int a[MAXN], n, cnt; //If there are multiple sets of data cnt remember to clear 0 void merge_sort(int l, int r) { if(l + 1 >= r) return; int m = (l + r) / 2; merge_sort(l, m); merge_sort(m, r); int p = l, q = m, i = l, t[MAXN]; while(p < m || q < r) { if(q >= r || p < m && a[p] <= a[q]) t[i++] = a[p++]; else t[i++] = a[q++], cnt += m - p; // just add this sentence } REP(i, l, r) a[i] = t[i]; } intmain() { scanf("%d", &n); REP(i, 0, n) scanf("%d", &a[i]); merge_sort (0, n); REP(i, 0, n) printf("%d ", a[i]); printf("\n%d\n", cnt); return 0; }