Nlogn solution for Inverse logarithm: Merge and sort, tree array and line segment tree

Source: Internet
Author: User
ArticleDirectory
    • Definition
    • Simple Enumeration
    • Solve with the thought of merging and sorting
    • Use the data structure that supports interval Modification
Definition

For an array of N non-negative integers A [1 .. n]. If I <J, and a [I]> A [J], it is called (A [I], a [J]). it is a reverse direction pair in array.

For example, there are (), () in the reverse order of an array.

Simple Enumeration

The complexity of O (N ^ 2) is achieved through a dual loop.ProgramIt will not be written.

Solve with the thought of merging and sorting

There are a lot of ideas on the Internet, and it is not difficult to understand the Merge Sorting. The specific Merge Sorting is not introduced. Here the rqnoj 173Code

VaR A, B: array [1 .. 1000000] of longint; I, j, k, n: longint; ans: int64; Procedure mergesort (L, R: longint); var I, J, K, M: longint; begin If L> = r then exit; M: = (L + r) SHR 1; mergesort (L, M); mergesort (m + 1, R); I: = L; j: = m + 1; K: = L; repeatIf A [I]> A [J] Then begin B [k]: = A [J]; Inc (ANS, M-I + 1 ); // The key lies in this step INC (j); Inc (k); End Else Begin B [k]: = A [I]; Inc (k); Inc (I); end until (I> m) or (j> r ); While I <= m Do Begin B [k]: = A [I]; Inc (k); Inc (I); end; While J <= r Do Begin B [k]: = A [J]; Inc (k); Inc (j); end; For I: = L to R Do A [I]: = B [I]; end; begin readln (N ); For I: = 1 to n Do Read (A [I]); mergesort (1, N); writeln (ANS); end.
Use the data structure that supports interval Modification

You can use the line segment tree and tree array to find the reverse logarithm in nlogn time.

A pair of numbers is a reverse order and only applies to I <J & A [I]> A [J].

Process

We insert the elements in the sequence in reverse order. inserting a [I] means update (A [I], 1 ). Ans + = getsum (1, a [I]-1) before each insert ). Finally, ANS is the reverse logarithm.

Correctness

Because it is inserted in reverse order, the subscript of the element in getsum is larger than I, and the query a [I]-1 meets the condition that the value is smaller than a [I.

These two operations are typical applications of line tree and tree array. They should be more proficient in writing than less commonly used Merge Sorting. In addition, the tree array code can be written very short.

 

 

The following is the code for HDU 1394:

 /*  A sequence composed of 0 .. n-1. Each time, you can move the first element of the team to the end of the team to find the number of minimum reverse pairs of the N sequences.    Algorithm:  Returns the reverse order of a tree array. When element I is added, the value of a [I] under element I is + 1, from the end of the team to the first of the team,  The logarithm of the reverse order + = getsum (I-1) when you join the queue, that is, the number of elements whose subscript is greater than it but whose value is smaller than it.   Because the tree array cannot process the element whose subscript is 0, when each element enters + 1, other programs should adjust accordingly.    After finding the number of reverse pairs of the original sequence, move the first element to the end of the team. The reverse logarithm is  The original reverse logarithm + number of elements greater than I-number of elements smaller than I, because it is 0 .. n, it is easy to calculate directly, every time you update Min.    Experience: do not copy other people's programs. If the details are different, debugging will take a long time.  */ # Include <stdio. h> # Define Maxn 10000 Int C [maxn], a [maxn], N; Int Min ( Int A, Int B ){ If (A <B) Return A; Else  Return B ;} Int Lowbit ( Int I ){ Return I &-I ;} Void Update ( Int I, Int X ){ While (I <= N) {C [I] + = x; I + = lowbit (I );}} Int Getsum ( Int X ){ Int Sum = 0; While (X> 0) {sum + = C [X]; X-= lowbit (x );} Return SUM ;}Int Main (){ While (Scanf ( "% D" , & N) = 1 ){ For ( Int I = 1; I <= N; I ++) C [I] = 0; Int Sum = 0; For ( Int I = 1; I <= N; I ++) {scanf ( "% D" , & A [I]);} For ( Int I = N; I> = 1; I --) {update (A [I] + 1, 1); sum + = getsum (A [I]);}Int Ans = sum; For ( Int I = 1; I <= N; I ++) {sum = sum-A [I] + (n-A [I]-1); ans = min (ANS, sum);} printf ( "% D \ n" , ANS );} Return 0 ;}
 
 
 
Line Segment Tree Code:
 /*  A sequence composed of 0 .. n-1. Each time you move the first element of the team to the end of the team,  Evaluate the number of minimum reverse pairs of the N sequences  Algorithm: inserts an element into the line segment tree in sequence. The reverse logarithm of each addition is larger than the inserted  Number of elements, which can be maintained by the line segment tree. Since the element value is 0 .. n, you can find the increase or decrease of each movement.  The number of Reverse Order pairs is updated. Experience: The line segment tree has been knocked on for 20 minutes. If it is Pascal and it is ugly, it should be able to be written for 10 minutes.  Debug for 10 minutes, mainly because the maximum reverse logarithm of the wrong question is not considered during the update.    */ # Include <stdio. h> # Define Maxn 100000 # Define Root 1 Struct Node { Int Left, right, sum;} t [maxn]; Int Val [maxn]; Int N; Void Build ( Int P, Int Left, Int Right ){Int M; t [p]. Left = left; t [p]. Right = right; t [p]. Sum = 0; If (Left = right) Return ; M = (left + right)/2; build (p * 2, left, m); Build (p * 2 + 1, m + 1, right );} Void Update ( Int P, Int Goal, Int Add) {T [p]. Sum + = add; If (T [p]. Left = T [p]. Right) Return ; Int M = (T [p]. Left + T [p]. Right)/2; If (Goal <= m) Update (p * 2, goal, add );If (Goal> m) Update (p * 2 + 1, goal, add );} Int Getsum ( Int P, Int Left, Int Right ){ If (Left> right) Return 0; If (T [p]. Left = left & T [p]. Right = right) Return T [p]. sum; Int M = (T [p]. Left + T [p]. Right)/2; If (Right <= m) Return Getsum (p * 2, left, right );Else   If (Left> m) Return Getsum (p * 2 + 1, left, right ); Else   Return Getsum (p * 2, left, m) + getsum (p * 2 + 1, m + 1, right );} Int Main (){ While (Scanf ( "% D" , & N) = 1) {build (root, 0, n-1 ); Int I, sum = 0, ans; For (I = 1; I <= N; I ++) {scanf ( "% D" , & Val [I]); sum + = getsum (root, Val [I], n-1); Update (root, Val [I], 1 );} ans = sum; For (I = 1; I <= N; I ++) {sum = sum + (n-Val [I]-1)-Val [I]; ans = sum <ans? Sum: ans;} printf ( "% D \ n" , ANS );} Return 0 ;}

Poj 3067

 /*  Question: The cities in the left and the cities in the right are located on several roads in the middle to find the intersection.    Algorithm: Convert to reverse order. The two roads have an intersection when and only when a. x <B. X & A. Y> B. Y. Takes path X as the first keyword After Y is the second keyword in ascending order, the reverse order of Y is obtained. Tree Arrays can be solved.    In addition, there is a complexity of Mn method, see http://www.cnblogs.com/penseur/archive/2011/04/14/2015998.html    Note:  1. K of questions is very large. The array must be large.  2. Because the tree array cannot process the element whose subscript is 0, 1 is added to all the y labels during input.    Gains and feelings:  1. reviewed the method of using the interval and inverse order pair.  2. Learned to call the qsort Function  3. Further understanding of pointers    A little nonsense:  This question has been done for a day !!! A whole day !!! The information on the Internet is not credible. Please give a compilation error code !!! The key moment is to look at K & R.  Ah !!! Maxm and maxn have been debugging for a long time ~~~     */ # Include <stdio. h> # include <stdlib. h> # Define Maxn 1100 # Define Maxm 1000100 Int N, m, K; Struct Point { Int X, Y;} A [maxm]; Long   Long C [maxn]; Int Lowbit ( Int I ){ Return I &-I ;} Long   Long Getsum (Int I ){ Long   Long Sum = 0; While (I> 0) {sum + = C [I]; I-= lowbit (I );} Return SUM ;} Void Add ( Int I ){ While (I <= maxn) {C [I] ++; I ++ = lowbit (I );}} Int CMP ( Const   Void *, Const   Void * B ){ Struct Point * c = (Struct Point *); Struct Point * D = ( Struct Point *) B; If (C-> X = D-> X) Return D-> Y-C-> Y; Return D-> X-C-> X ;} Int Main (){ Int T, J, I; Long   Long Ans; scanf ( "% D" , & T ); For (J = 1; j <= T; j ++) {ans = 0; scanf ( "% D" , & N, & M, & K); memset (C, 0, Sizeof (C )); For (I = 1; I <= K; I ++) scanf ( "% D" , & A [I]. X, & A [I]. y ); For (I = 1; I <= K; I ++) A [I]. x ++; qsort (a + 1, K, Sizeof (A [0]), CMP ); // For (I = 1; I <= K; I ++)      // Printf ("% d \ n", a [I]. X, a [I]. y );      // Printf ("\ n ");          For (I = 1; I <= K; I ++) {ans + = getsum (A [I]. y-1); add (A [I]. y);} printf ( "Test Case % d: % LLD \ n" , J, ANS );} Return 0 ;}
 
 
 
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.