Counting Inversions using BIT

前端 未结 1 900
滥情空心
滥情空心 2021-02-08 06:26

I know this question has been discussed before, but i am interested in doing this using a Binary Indexed Tree. I found this link to show how to do it.I did not quite follow th

相关标签:
1条回答
  • 2021-02-08 07:28

    An inversion occurs when an element is larger than some element that follows it in the array.

    We can count inversions by grouping them by second element. For example, in the array [4, 3, 1, 2], the element pairs (4, 3), (4, 1), (4, 2), (3, 1), and (3, 2) are inversions. We group them by second element, hence: [[(4, 1), (3, 1)], [(4, 2), (3, 2)], [(4, 3)]].

    We consider each element in turn, and count how many inversions it is the second element of. In the example, the element 4 is the second element in 0 inversions, the element 3 in 1 inversion, and the elements 1 and 2 in 2 inversions each.

    In order for any given element to be the second element of an inversion, there has to be a larger element somewhere before it in the array.

    We perform the count efficiently by traversing the array from left to right and always keeping track of how many elements of each value have been encountered so far, using a BIT. Initially our frequency table will be [0, 0, 0, 0], since we've seen no elements at all. After we visit the 4, we update its frequency, giving [0, 0, 0, 1]. After visiting the 3, [0, 0, 1, 1], and so on.

    Each time we visit a position, we use the BIT to find out how many elements visited so far are greater than it. So for example when we encounter the 1, the BIT currently contains [0, 0, 1, 1], representing that there were so far zero 1's and 2's, one 3, and one 4. By adding the values 0 + 1 + 1, we count the number of elements so far that are greater than 1.

    Adding all these individual counts gives the total number of inversions.

    Note that, in general, you must employ coordinate compression in order for this to be efficient. For example, if your initial array contains numbers like A = [92, 631, 50, 7], you shouldn't allocate a BIT with hundreds of elements. Instead, sort the array to determine that 7 < 50 < 92 < 631, which allows us to assign the ranks 7 => 1, 50 => 2, 92 => 3, 631 => 4; then replace each element by its rank, giving B = [3, 4, 2, 1]. The number of inversions of this array will be the same as in the original, since B[i] > B[j] if and only if A[i] > A[j].

    (Note: A real programmer would probably use indices starting from zero.)

    0 讨论(0)
提交回复
热议问题