The original intention of the question is to sort by merging. I just learned the tree array and used it.
Discretization of tree Arrays
Discretization is a powerful tool for borrow because the data range is too large. For example, there are four numbers: 99999999, 123, and 1583. The data range is too large, the range opened by the C array in the tree array is the data range. In this case, the number of the four numbers must be classified as 1 2 3 4 at a time (that is, the first number, the second number ...), Sort the key values in order of 2, 3, 4, 1 (that is, the second number and the third number in ascending order ...), Therefore, the second number is the smallest, that is, F [2] = 1, F [3] = 2, F [4] = 3, F [1] = 4, that is, to change the key value to 1 ~ N, the relative size remains unchanged, that is, 4 1 2 3.
Store data in the f [] ArrayRelative sizeTo reference the I-th element of the original arrayF [I]Now
The data given by the question is maxn = 500000, the exact reverse order number is the first n of the arithmetic difference series and = (maxn-1) * maxn/2, almost 10 to the power of 13, so to useLonglongStorage
# Include <iostream> # include <cstring> # include <algorithm> # include <cstdio> # define maxn 500010 typedef long ll; using namespace STD; struct node {int X, i;} A [maxn]; int N; int C [maxn], F [maxn]; bool CMP (node X, node y) {return X. x <Y. x;} int lowbit (int x) {return X &-X;} void Update (int x, int v) {While (x <= N) {c [x] + = V; x + = lowbit (x) ;}} int getsum (int x) {int sum = 0; while (x> 0) {sum + = C [X]; X-= lowbit (x);} return Su M;} int main () {While (~ Scanf ("% d", & N), n) {memset (C, 0, sizeof (c); memset (F, 0, sizeof F ); for (INT I = 1; I <= N; I ++) {scanf ("% d", & A [I]. x); A [I]. I = I; // subscript of the original array} Sort (a + 1, A + n + 1, CMP); // start discretization f [A [1]. i] = 1; // start from the smallest for (INT I = 2; I <= N; I ++) {if (a [I]. x! = A [I-1]. x) {f [A [I]. i] = I;} else f [A [I]. i] = f [A [I-1]. i];} // discretization ends ll ans = 0; For (INT I = 1; I <= N; I ++) {Update (F [I], 1 ); ans + = I-getsum (F [I]); // The reverse order of the number of I = I-the first number is smaller than it = the first number is greater than it, getsum (I) that is, how many numbers are earlier than I} // can also be written as ans + = getsum (N)-getsum (I) cout <ans <Endl;} return 0 ;}