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

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

Given a sequence A of N pairwise-distinct integers. There are Q queries L R K, asking for the k-th element in the increasing-sorted subsequence A[L], A[L+1], ...., A[R-1], A[R]. The original sequence never changes.

  • 1 ≤ N, Q ≤ 10^5

  • |Ai| ≤ 10^9, 1 ≤ i ≤ N

  • 1 ≤ L ≤ R ≤ N

  • 1 ≤ K ≤ R-L+1

Example:

Input:

7 (N)

2 1 5 4 3 6 8 (sequence A)

4 (Q)

1 2 2 (L R K)

3 7 4

4 6 2

5 5 1

Output:

2

6

4

3

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

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

This problem exist on spoj MKTHNUM

here is my O((N+M) sqrt N) solution:

solution

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

    Could someone explain me this solution please?

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

      LushoPlusPlus So the idea is to replace each element of the given array by it's compressed value [index of this element if we sort the whole array]. It's simply done in $$$O(n.log(n))$$$. Also, save the inverse mapping, i.e. $$$pos[compressed$$$ $$$value(a[i])] = i$$$.

      Now, we will use this array $$$pos[1..n]$$$ to answer queries $$$l,r,k$$$. How ? the first index $$$i$$$ such that $$$l \le pos[i] \le r$$$ will be the smallest compressed value in $$$a[l..r]$$$. Next index satisfying the inequality will be second smallest value and so on. We have to find the $$$k_{th}$$$ such index.

      Build partial frequencies of each element [and for each block]. Break $$$a[1..n]$$$ into $$$\sqrt n$$$ blocks. Iterate through blocks and in each, find number of elements satisfying the inequality use partial frequencies. The first block where number of elements $$$\ge k$$$, traverse it using brute force.

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

    kingofnumbers did you find a way to perform point updates as well in this problem?

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

O(M log^2 N) solution is here

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

It can be solved in O((N + M)log(N)) using persistent segment trees: let's replace all numbers with numbers in range 1..N, and then for each prefix we can callculate a tree, such that nth position in a tree is a number of occurences of n in that prefix. Imagine a segment tree made by the same rule for subsegment [L, R]. each vertex of such a tree is a difference of a corresponding vertex in tree for [1..r] and such a vertex in tree for [1..l-1]. So we can implicitly acess vertex v of such tree simply by subtracting corresponding vertexes. Having a tree for [L..R] let us find an onswer quickly by simple recursive procedure in this tree. I'm sorry for explanation that's not very clear, but the solution is here

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

    I got the idea and it's interesting , but I am not able to understand how you create a tree for each prefix (total n trees) without having complexity O(N^2) , I also couldn't understand the code can you give quick explanation for each variable, array and function in this code

    thanks.

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

      I use persistent segment tree to create n trees in O(nlogn) time. That means, that I do not modify any tree node. Instead I create a new node every time. This way I can always use any old version of a tree. Each update operation on a segment tree takes O(logN) time, O(logN) additional memory and produces a root of new segment tree, that reuses some parts of an old one. Anytime a node would be modified in a simple segment tree a new node with another value should be created in a persistent one. A tree for [1...k] is just tree for [1..k-1] where some element with a value x is replaced to some element with value (x + 1).

      I slightly modified the code for it to fit to SPOJ version of a problem, though I didn't change the point. This version gets AC on SPOJ.

      About functions:

      allocate(x = 1) allocates exactly x segment tree nodes from a constant array. A pointer to the first of them is returned

      update(v, vl, vr, x) increases by one the value of x node in subtree tree rooted in v, where [vl; vr-1] is segment corresponding to that subtree. In all outer functions it is used that way: update(v, 0, maxn, x). That functions returns the root of a new subtree leaving the original untouched.

      find_nth(u, v, vl, vr, nth) finds an nth element on a tree that is difference of v and u. vl and vr are the boundaries of a subsegment this function is operating on now. It returns a pair of a current result and a flag — should we continue searchin to the right, or not. That flag is not used outside of that function

      array — input array

      coords — sorted input array. It is used to replace numbers in range [-10^9; 10^9] with numbers in range [0...n-1]

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

Great problem! I really enjoyed learning about persistent segment trees, thinking an implementation and then coding it.

New knowledge is always welcome :)

I got AC with that idea. Here is the code -> Code

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

Here is my solution http://ideone.com/iNSQ1M with O(M log^2 N) aproach. But i am getting TLE. Can anyone help?

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

spoj problem : http://www.spoj.com/problems/MKTHNUM/ i got AC using merge sort tree...here is my soln https://ideone.com/fork/CQI7qe

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

Can anybody explain how to do this question if elements in array can repeat also?

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

There's another method to solve this problem, which can support editing. (point)

Using segment tree and build a treap for each node on the tree. When we update a[i]'s value, we can go From root to leaves and update the treap which the node was on the path. One update is O(logn).

to finding kth-element, we can use Binary Search.

If we supposed that x is the answer: We all know that any range [L...R] can split into <=logn nodes on the segment tree. So we can find these nodes and using treap to find the rank of x in [L...R].

And we can use the result to change the answer.

(If anyone already explains about it, please ignore me)