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

Автор enigmaavkm, история, 9 лет назад, По-английски

Problem:

We have given an array A[] of size N. Now we have given Q queries, each queries consist of three integer l,r,k where:

1<=l<=r<=N
1<=k<=(r-l+1)
1<=N,Q<=10^5

Now,we want to find out the sum upto the k element of the sorted sub-array from l to r.

For example:

N=6 and array element be 5,1,7,4,6,3 And Q=1 where l,r,k be as 2,5,3. then sub-array from index 2 to index 5 be {1,7,4,6} after sorting it becomes as {1,4,6,7} so sum upto k=3 term is equal to (1+4+6)=11 so answer is 11 .

I have tried using sorting of each sub-array and then sum, it takes Q*N*log(N) time complexity in worst case. Please help to find any better solution within time complexity less than Q*N in worst case.

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

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

You can just use Mo's algoritm link.
So you can store current elements in treap or segment tree to find sum. It will work in O(n*sqrt(n)*log(n)+q*log(n))

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

Also it can be done in O(q*log(n)*log(n)).
Let's build segment tree and in node you store all elements in this range in increasing order. So to answer query you can do binary search to find kth element. And then using prefix sum find sum.

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

Also it can be done with a persistent segment tree in , where MAX is the maximum number in the array.

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

    can u pls explain how to do this as i have not used persistent segment tree before. specifically on what conditions to build. tia

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

      Let's have one version for every prefix of array. If you want go from prefix R to R + 1 you create new version and add 1 to position a[R + 1]. In every node of tree you store sum of elements in this range and their amount. To answer query (l, r, k) you take two vesions l - 1 and r. So you start from root. If rootr.cnt - rootl - 1.cnt = k then ans +  = rootr.sum - rootl - 1.sum and break, else if left[rootr].cnt - left[rootl - 1].cnt > k then you make rootr = left[rootr] and rootl - 1 = left[rootl - 1] and continue, else ans +  = left[rootr].sum - left[rootl - 1].sum, delete this elements from k k -  = left[rootr].cnt - left[rootl - 1].cnt and go to the right rootr = right[rootr] rootl - 1 = right[rootl - 1] and continue.

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

    Conceptually easiest solution and best time complexity.

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

Can you, please, share the problem link?

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

Also it can be done with a parallel binary search in O((N + Q) * log(N)2).