Why can a line segment tree calculate the number of reverse orders?
to give a simple sequence 9 5 3, the reverse order number is 3
first, a reverse order number is required in two ways: you can find values smaller than the current element from the beginning to the end, or you can find values larger than the current element from the back to the end. There are several reverse order numbers.
the line segment tree is used to find a large number of values from the back of the application. (Update and query)
the current number is n = 10
element 9 5 3
9 is added to the line segment tree first, T [9] + = 1; check the value from T [9] to T [10] greater than 9, without sum = 0;
5 add the line segment tree, T [5] + = 1, check the value from T [5] to T [10] greater than 5, there is a 9, sum + = 1;
3 add a line segment tree, t [3] + = 1, and query values greater than 3 from T [3] to T [10]. There are two 9 and 5 values, sum + = 2;
final sum = 3;
If the element value cannot be determined, first let's talk about discretization of the series, which is enumerated from the beginning to the end, find a smaller number of statistics ......
discretization: for example, 2 5 8 3 10 is equivalent to 1 3 4 2 5, which can be solved by sorting and adding small processing.
example:
element 9 5 3 4 1 discretization to obtain the index
Index 1 2 3 4 5
sort elements in ascending order
element 1 3 4 5 9
index 5 3 4 2 1
count by I, we need to find the number from 1 to the I-1 which is greater than a [I], update the answer.
what should I do?
insert a number into the line segment tree after each enumeration (Note: insert it to the corresponding position ).
example: 3 2 4 1. The line segment tree should change to T [3] + = 1; t [2] + = 1; t [4] + = 1; t [1] + = 1;
set X = A [I]. In this way, when inserting a number X, evaluate t [x + 1] ~ The sum of T [N]. The sum is 1 ~ Number of numbers in the I-1 greater than a [I]
because the number of reverse orders of a series can be obtained from two
When you insert a [I], how many numbers are there before a [I ]?
Poj 2299 # include <iostream> # include <cstdio> # include <cstdlib> # include <cstring> # include <algorithm> # include <cmath> using namespace STD; # define Max int_max # define min int_min # define ll _ int64 # define Init (a) memset (A, 0, sizeof (A) # define lson l, m, RT <1 # define rson m + 1, R, RT <1 | 1 const int maxn = 500010; using namespace STD; int T [maxn <2], index [maxn], num [maxn]; int N; int CMP (const int I, Const Int J) {return num [I] <num [J];} void Update (INT L, int R, int RT, int num, int add) {T [RT] + = add; If (r = L) return; int M = (L + r)> 1; if (Num <= m) update (lson, num, add); else Update (rson, num, add);} int query (int l, int R, int RT, int L, int R) {If (L <= L & R <= r) return T [RT]; int M = (L + r)> 1; int ans = 0; if (L <= m) ans + = query (lson, L, R); If (r> m) ans + = query (rson, L, R); retur N ans;} int main () {While (~ Scanf ("% d", & N) {If (n = 0) break; Init (INDEX); For (INT I = 1; I <= N; I ++) {scanf ("% d", & num [I]); Update (1, n, 1, I, 1 ); // discretization index [I] = I;} Sort (index + 1, index + n + 1, CMP); // sort num and update index ll sum = 0; for (INT I = 1; I <= N; I ++) {sum + = (query (1, n, 1, 1, index [I])-1 ); update (1, n, 1, index [I],-1);} printf ("% i64d \ n", sum);} return 0 ;}
HDU 1394
A group of Numbers Place the first element at the end of each time to generate a new sequence, and then count the number of reverse orders to find the minimum value in all reverse orders.
There is a formula: first obtain the reverse number of the original series, Sum
Then the number of new reverse orders each time = sum-A [I] + (n-A [I]-1)
# Include <iostream> # include <cstdio> # include <cstdlib> # include <cstring> # include <algorithm> # include <cmath> using namespace STD; # define Max int_max # define min int_min # define ll _ int64 # define Init (a) memset (A, 0, sizeof (A) # define lson l, m, RT <1 # define rson m + 1, R, RT <1 | 1 const int maxn = 500010; using namespace STD; int T [maxn <2], index [maxn], num [maxn]; int N; int CMP (const int I, const Int J) {return num [I] <num [J];} void Update (INT L, int R, int RT, int num, int add) {T [RT] + = add; If (r = L) return; int M = (L + r)> 1; if (Num <= m) update (lson, num, add); else Update (rson, num, add);} int query (int l, int R, int RT, int L, int R) {If (L <= L & R <= r) return T [RT]; int M = (L + r)> 1; int ans = 0; if (L <= m) ans + = query (lson, L, R); If (r> m) ans + = query (rson, L, R ); return ans;} I NT main () {While (~ Scanf ("% d", & N) {If (n = 0) break; Init (INDEX); For (INT I = 1; I <= N; I ++) {scanf ("% d", & num [I]); Update (1, n, 1, I, 1); index [I] = I ;} sort (index + 1, index + n + 1, CMP); LL sum = 0; For (INT I = 1; I <= N; I ++) {sum + = (query (1, n, 1, 1, index [I])-1); Update (1, n, 1, index [I], -1);} // printf ("% i64d \ n", sum); LL ans = sum; For (INT I = 1; I <= N; I ++) {sum = sum-num [I] + (n-num [I]-1); ans = min (sum, ANS) ;}cout <ans <Endl ;} return 0 ;}