Question:
For a sequence of n numbers a1, a2,..., an, the range of these numbers is 0 ~ N-1, you can move the number of m above to the back to form a new sequence:
A1, a2,..., an-1, an (where m = 0-the initial seqence)
A2, a3,..., an, a1 (where m = 1)
A3, a4,..., an, a1, a2 (where m = 2)
...
An, a1, a2,..., an-1 (where m = N-1)
What is the minimum number of reverse sequences?
Analysis and Summary:
(1) When I first read this question, I felt familiar with it, so I read the answer record. I did = last year, but at that time I directly tried to find the reverse order of the data...
Then we want to use the line segment tree for optimization. The so-called reverse order number is actually the sum of each number in the sequence, which is greater than the number before it.
Use the line segment tree to record the numbers. The value of the interval [a, B] indicates the number ~ The number of times that B has appeared, so for ai, you only need to query the number of [ai, n] (the number of ai that was earlier than ai ), it indicates the number of reverse orders of ai.
(2) After finding the reverse numbers of a1, a2,..., an-1, and an, You Can recursively obtain the reverse numbers of other sequences. Suppose we want to move a1 to an, then we split the process into two steps:
1. Remove a1. Through observation we can find that (a1-1) is 0 ~ The number of numbers smaller than a1 in n-1, because a1 is smaller than a1 in the first sequence, so there are (a1-1) after a1 than a1, so the formation of (a1-1) on the reverse order number, when a1 is removed, the total number of reverse orders of the original sequence is reduced (a1-1.
2. Add a1 to. 0 ~ N-1, a number larger than a1 total (n-a1) number, because a1 is now in the last, that is, before it total (n-a1) number is greater than it, that is, increased (n-a1) number of reverse orders.
Combining the two steps of 1, 2, set the original sequence Inverse Order Number to sum, when the original sequence first to move to the last position, the reverse order number to: sum = sum-(ai-1) + (n-ai );
Code:
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Define lson (x) (x <1)
# Define rson (x) (lson (x) | 1)
Using namespace std;
Const int MAX_NODE = 5005 <2;
Int arr [MAX_NODE];
Struct node {
Int left, right;
Int num;
Int mid () {return (left + right)> 1 ;}
Bool buttom () {return left = right ;}
};
Class SegTree {
Public:
Void build (int cur, int left, int right ){
T [cur]. left = left;
T [cur]. right = right;
If (left = right ){
T [cur]. num = 0;
Return;
}
Int m = t [cur]. mid ();
Build (lson (cur), left, m );
Build (rson (cur), m + 1, right );
Push_up (cur );
}
Void update (int cur, int data ){
++ T [cur]. num;
If (t [cur]. buttom ()){
Return;
}
Int m = t [cur]. mid ();
If (data <= m)
Update (lson (cur), data );
Else
Update (rson (cur), data );
}
Int query (int cur, int left, int right ){
If (t [cur]. left = left & t [cur]. right = right ){
Return t [cur]. num;
}
Int m = t [cur]. mid ();
If (right <= m)
Return query (lson (cur), left, right );
Else if (left> m)
Return query (rson (cur), left, right );
Else
Return query (lson (cur), left, m) + query (rson (cur), m + 1, right );
}
Private:
Void push_up (int cur ){
T [cur]. num = t [lson (cur)]. num + t [rson (cur)]. num;
}
Node t [MAX_NODE];
};
SegTree st;
Int main (){
Int n, x;
While (~ Scanf ("% d", & n )){
St. build (1, 1, n );
Int sum = 0;
For (int I = 0; I <n; ++ I ){
Scanf ("% d", & arr [I]);
++ Arr [I];
Int tmp = st. query (1, arr [I], n );
Sum + = tmp;
St. update (1, arr [I]);
}
Int _ min = sum;
For (int I = 0; I <n-1; ++ I ){
Sum = sum-(arr [I]-1) + (n-arr [I]);
If (sum <_ min) _ min = sum;
}
Printf ("% d \ n", _ min );
}
Return 0;
}