Блог пользователя passworld

Автор passworld, 11 лет назад, По-английски

I want to count for every number ,say A[i] ,how many numbers there are that is smaller than Ai with id smaller than i. For example , here is an array: 5 3 7 2 9 6 ,the anwser is 0 0 2 0 4 3 Is there any fast algorithm that can solve this problem? Thank you for your help!

  • Проголосовать: нравится
  • -2
  • Проголосовать: не нравится

»
11 лет назад, скрыть # |
 
Проголосовать: нравится +19 Проголосовать: не нравится

Use Fenwick Tree, add 1 to tree[A[i] and ask for sum on tree[0...A[i] - 1]

»
11 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +11 Проголосовать: не нравится

the problem can be solved with O(nlogn) complexity using segment tree:

Consider the array b[] where b[i] denotes the number of elements of A that are <=i

Traverse the array A[] from left to right, editing the array b[] on your way by adding 1 on the interval from A[i] to Max number in A[]. The answer for ith number is b[A[i]-1]

please correct me if I am wrong.

  • »
    »
    11 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +11 Проголосовать: не нравится

    And changing limit for A[i] does not make much difference for this solution. You just have to compress all input numbers — say that smallest of them is equal to 1, second smallest is equal to 2 and so an. There will be no more than N different values in array of size N, so you'll end up with array of numbers <=N, even if original numbers were up to 1e18.

»
11 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

What you're asking is similar to counting the number of inversions, though the comparison is the other way around. It can be solved with BIT / Segment Tree, like others have said, and also with a modified Merge Sort algorithm.

»
11 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

If i didnt get the question wrong it can be solved with a monotonic queue with O(n) time complexity.

EDT: Yes i did get it wrong. Sorry.

»
11 лет назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

The problem can be solved without compressing the numbers.
Put Fi = 0 for all i <  = N
Sort the pairs Pi = (Ai, i).
Then go from left to right, calculate the answer for Pi.second, which is (F1 + ... + FPi.second - 1). Do this with segment tree.
Then put FPi.second = 1