Question link: http://poj.org/problem? Id = 2299
Ideas:
The number of reverse orders is the number of exchanges, so you can find the reverse Number of the sequence.
According to the divide and conquer method, the sequence is divided into two parts of the same size, respectively, to find the number of reverse orders of the sub-sequence; for each number in the right sub-sequence, find the number larger than its number in the left sequence, the sum of computation is the solution.
In addition, when merge is used for sorting, it is easy to obtain the number larger than the number of each number in the right subsequence.
Code:
#include <stdio.h>#include <limits.h>long long Count = 0;const int MAX_N = 500000 + 10;long long A[MAX_N], L[MAX_N], R[MAX_N];void Merge(long long A[], int p, int q, int r){ int i, j, k; int n1 = q - p + 1; int n2 = r - q; for (int i = 0; i < n1; ++i) L[i] = A[p + i]; for (int j = 0; j < n2; ++j) R[j] = A[q + j + 1]; i = j = 0; k = p; L[n1] = INT_MAX; R[n2] = INT_MAX; while (k <= r) { if (L[i] > R[j]) { A[k++] = R[j++]; Count += n1 - i; } else A[k++] = L[i++]; }}void Merge_Sort(long long A[], int p, int q){ int r = (p + q) / 2; if (p < q) { Merge_Sort(A, p, r); Merge_Sort(A, r + 1, q); Merge(A, p, r, q); }}int main(){ int n; while (scanf("%d", &n) == 1) { if (n == 0) break; Count = 0; for (int i = 0; i < n; ++i) scanf("%d\n", &A[i]); Merge_Sort(A, 0, n - 1); printf("%lld\n", Count); } return 0;}
Poj 2299 ultra-quicksort