The number of reverse order refers to the example: Array a={2,4,3,5} then <4,3> is an inverse number.
One: Violent match
For the elements in array a, I from 0 to n-1,j from I+1 to N, judging whether each is an inverse number, time complexity O (LgN). It's too simple to write code ...
Two: Merge
The merge sort can solve the reverse order number mainly lies in: for example merges a1={2,4,5}, a2={1,3}, merges, each time we judge A1 and A2 element size, here have two kinds of ideas:(1)whenA1[i] <=a2[j], you need to putA1[i], we can calculate what has been put inA2the number of elements in thej-mid-1; ideas(2)whenA1[i] <=a2[j], we don't care about it, just put it in, but whenA1[i] >a2[j],at this point you need to putA2[j], let's calculateA1How many of the elements are not putmid–i+1, theyA2[j]The corresponding number of reverse order. The idea of a merge algorithm has two needs to be modified, the idea of two only one place to modify it. Time Complexity of O (LgN)
Idea (1) code:
void Mergesortinversenumber (int a[], int p, int q, int a1[], long long int &number) {if (P < q) {int r = (p+q)/2;merge Sortinversenumber (A, P, R, A1, number); Mergesortinversenumber (A, r+1, Q, a1, number); int i = p, j = r+1;int k = P;while (i <= R && J <= Q) {if (A[i] <= a[j]) {a1[k++] = A[i++];number + = j-r-1; Put A[i] in the SEQ2 in the number of the number is in reverse order}elsea1[k++] = a[j++];} if (i > R) {while (J <= q) a1[k++] = a[j++];} Else{while (i <= R) {a1[k++] = A[i++];number + = j-r-1; There is also a need to modify}}for (int i = p; I <=q; i++) a[i] = A1[i];}}
Idea (2) code:
void MergeSortInverseNumber2 (int a[], int p, int q, int a1[], long long int &number) {if (P < q) {int r = (p+q)/2;merg Esortinversenumber (A, P, R, A1, number); Mergesortinversenumber (A, r+1, Q, a1, number); int i = p, j = r+1;int k = P;while (i <= R && J <= Q) {if (A[i] <= a[j]) a1[k++] = a[i++];else{a1[k++] = A[j++];number + = r-i + 1; Put A[j] in the seq1 when there are still how many elements are not placed in reverse order number}}if (i > R) {while (J <= q) a1[k++] = a[j++];} Else{while (i <= r) a1[k++] = a[i++];} for (int i = p; I <=q; i++) a[i] = A1[i];}}
Three: tree-like array
The tree array solution is very difficult to understand, I have not understood, do not need to understand. Here is a code on the Internet:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include < String.h>using namespace Std; const int Maxn=500005;int n;int AA[MAXN]; discretized array int C[MAXN]; Tree-like array struct node{int v; int order;} IN[MAXN]; int lowbit (int x) {return x& (-X);} void update (int t,int value) {int i; For (I=t;i<=n;i+=lowbit (i)) {c[i]+=value; }} int Getsum (int x) {int i; int temp=0; For (I=x;i>=1;i-=lowbit (i)) {temp+=c[i]; } return temp;} BOOL CMP (Node A, Node B) {return A.V<B.V;} int main () {int i,j; while (scanf ("%d", &n) ==1 && N) {//discretization for (i=1;i<=n;i++) {scanf ("%d", &am P;IN[I].V); In[i].order=i; } sort (in+1,in+n+1,cmp); for (i=1;i<=n;i++) aa[in[i].order]=i; A tree-like array for reverse memset (c,0,sizeof (c)); Long Long ans=0; for (i=1;i<=n;i++) {update (aa[i],1); Ans+=i-getsum (Aa[i]); } cout<<ans<<endl; } return 0;}
since the previous article Blog we know that any tree-like array can solve the problem, line tree can be solved, why not use line tree to solve it?
Four: line segment tree
The idea of
n Span style= "Color:rgb (54,46,43)", elements are also 1~n [1,n] x [x+1,n] [x,x] x 1 o (N), Span style= "Color:rgb (54,46,43)" >o (LgN).
Of course, this assumes that the element size is 1~n between, then if not in this interval what to do, then we can Compress discrete Data . Look at the following code:
The discretized data is compressed by the struct Arrayextend{int val;int index;};
int n;cin >> N;int *a = new int[n+1];// compress data by a struct to compress the range to 1~n the order remains the same arrayextend *a1 = new Arrayextend[n+1]; for (int i = 1; I <= N; i++) {cin >> a1[i].val;a1[i].index = i;} Sort (a1+1, a1+n+1, CMP); Sort A[a1[1].index] = 1;for (int i = 2; I <= N; i++) {if (A1[i].val = = A1[i-1].val) {A[a1[i].index] = a[a1[i-1].index];
//equal processing}elsea[a1[i].index] = i; Unequal processing}
Full code:
/* Function: Line tree to find reverse order number */#include <iostream> #include <algorithm> #include <cmath>using namespace std; #define MAXSIZE 100000#define M 300000//discrete data to compress the struct Arrayextend{int val;int index; BOOL CMP (arrayextend AE1, Arrayextend ae2) {return ae1.val < Ae2.val;} Segment tree node struct Node{int left, right, sum;} T[m];void build (int root, int start, int end) {//If equal is the leaf node returns if (start = = end) {t[root].sum = 0;t[root].left = Start;t[ro Ot].right = End;return;} int mid = (start+end) >> 1;build (root*2+1, start, mid); Create left subtree build (root*2+2, mid+1, end); Create right sub-tree T[root].sum = 0;t[root].left = Start;t[root].right = end;} A long long int getsum (int root, int qstart, int end) {if (Qstart > End) return 0;//if the query interval is greater than the unknown origin interval returns its value if (T[root].left > = Qstart && t[root].right <= end) return t[root].sum;int mid = (t[root].left + t[root].right) >> 1;if (Qst Art > Mid) return getsum (root*2+2, Qstart, end), Else return getsum (root*2+1, Qstart, end) + getsum (root*2+2, Qstart, en d);} // A value of index that will contain the interval of index sum+1 indicates how many number of void update (int root, int index) {if (T[root].left = = t[root].right) {t[root].sum + = 1) of the interval ; return;} int mid = (t[root].left + t[root].right) >> 1;if (Mid < index) update (root*2+2, index), else update (ROOT*2+1, index ); t[root].sum = T[root*2+1].sum + t[root*2+2].sum; Backtracking}int Main () {int n;cin >> n;int *a = new int[n+1];//compress data by a struct to compress the range to 1~n the order remains the same arrayextend *a1 = new arr ayextend[n+1];for (int i = 1; I <= N; i++) {cin >> a1[i].val;a1[i].index = i;} Sort (a1+1, a1+n+1, CMP); Sort A[a1[1].index] = 1;for (int i = 2; I <= N; i++) {if (A1[i].val = = A1[i-1].val) {A[a1[i].index] = A[a1[i-1].index]; Equal handling}elsea[a1[i].index] = i; Unequal handling of}build (0, 1, n); long long int ans = 0;for (int i = 1; i<= N; i++) {ans + = getsum (0, a[i]+1, N); Enter A[i] to find the number of elements between "a[i]+1,n" update (0, a[i]); Update segment Tree}cout << ans << endl;delete []a1;delete []a;return 0;}
Note that the node tree required to store a segment tree is the number of nodes with a full two-tree node of 2^ (Ceil (LOGN) +1)-1. In addition, the number of reverse order is a long long or hihocoder 39th week can only get 80 points. Because the data is 10^5, the number of reverse order can reach 5*10^9, and the int size is only 4*10^9 multipoint.
Several methods to find the number of reverse order