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

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

Hello There

So i found this Problem where i have to find the LIS of 10^5 pairs of integers

a pair is greater than another pair if x1<x2 and y1<y2 strictly

now finding LIS using a segment tree for such a large input is no issue ... but sorting the pairs kinda confused me

any ideas or hints how should i think about this problem ?

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

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

I would do it with 2d segment tree for max. The LIS for the current position is just max in rectangle [(0, 0) — (xi — 1, yi — 1)] + 1. After that we need to update current position (xi, yi) with the current value of LIS. Its really similar to the solution of LIS of integers except the fact it uses 2d segment tree/BIT. In my opinion this solution is much easier to write and understand.

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

    How could be the implementation of a 2D segment tree with those constraints? I know we can do some coordinate compression, but still there may be 10^5 different x and y coordinates.

    Sorry, I've never done a 2D segment tree. I thought that 2D segment trees were Quad Trees, but it seems they are segment trees whose nodes are segment trees too @_@

    • »
      »
      »
      9 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится +4 Проголосовать: не нравится

      Sorry it took so long, but it ca easily be done using max dynamic fenwick or dynamic segment tree. Or just by making it a segment tree in every node of which there is an implicit treap (or just treap). Or just compress the cordinates.

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

        You say "easily", but that doesn't sound easy at all for me hahaha. I got a lot to learn then.

        Thanks!

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

    but what about memory ??

    the concept is beautiful and new to me ... but is there a way to implement it with constraints being 10^5 ??

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

You can just process all pairs by increasing y, and if some of them have the same y then process them by increasing x. Now if we are proccesing pair (xi, yi), then its' result ri equals to 1 + max rj where j < i, xj < xi. You can get this max by using segment tree where for each y you store maximal result of already proccesed pairs with exact y. Because cordinates can be up to 109, you need to compress them so you will be able to store them in tree (it's needed only for y). Answer for whole task is maximum result of all pairs.

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

    Wouldn't that be O(n) per query in the worst case?

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

      Why would it be? You are getting max rj in log n because it's just simple query on segment tree, and you update a tree also in log n.

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

        Sorry I didn't understand your approach very well.

        If you have 3 points (3,3), (2,2), (1,1), if you process them by increasing y (breaking ties with increasing x) wouldn't your algorithm produce 3 as an answer?

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

          Oh yea, I missunderstood a problem I thought it's set of point, my bad.

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

Numerous O(nlg^2n) solution exists for this problem, and this is my favorite solution.

dp formula is : dp[i] = Max(xj < xi, yj < yi, j < i) dp[j] + 1. In this formula we are considering all O(n^2) pairs one by one — which is slow. Now, I will calculate this table faster with divide & conquer approach.

Let solve(s, e) -> calculate all dp value pairs from s to e. What we will do is -

  • call solve(s, m) to get dp values (m = (s+e)/2)

  • "propagate" the dp values from [s, m] to [m+1, e]

  • call solve(m+1, e) to get the rest.

when we are doing D&C, we should still consider all O(n^2) pairs. This is why we propagate all the values from [s, m] to [m+1, e].

Naive propagation can be done by this short code :

for(i = [m+1, e]) update dp[i] to Max(xj < xi, yj < yi, j = [s, m]) dp[j] + 1

But notice that [s, m] and [m+1, e] are disjoint intervals — which eliminates the needs to consider for i < j. We can preprocess the values in [s, m] by sorting in xcoord & maintaining segment trees by ycoord. Now, updating values in [m+1, e] can be replaced by simple queries.

Time complexity is T(N) = 2T(N/2) + O(NlgN), we can show T(N) = O(Nlg^2N) by master's theorem. Memory complexity is O(N) (which is a lot better than 2d segtrees.)

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

I implemented a solution using 2D BIT with coordinate compression. We only create entries on the map as needed, so memory and runtime are both O(Nlog^2N). I used unordered_map to speed up the queries, but I'm still getting TLE #3.

I tested it on my computer and it runs in around 2 seconds for the worst test case, but the problem asks for runtime under 0.345 seconds...

I wonder if anyone has anything faster than O(Nlog^2N).

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

    Actually, my above solution can be optimized to NlgN since -

    • There is O(N+Q) RMQ.

    • Sorting step can be eliminated by mergesort-fashioned way (cache the result like merge sort tree)

    • since we can't update the linear RMQ, we should compress the coordinate at every recursion stage. Solution to this is similar as above.

    So better asymptotic is "possible". But I've never heard about "practical" O(nlgn) solution.

    btw if you are getting TL with 2d segtrees, I "strongly" recommend you to write above solution. I guess it will run at least 2-3 times faster than 2d segtrees (which are quite slow + memory hungry in practice).

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

      Hi, could you explain more on this algorithm? I don't see how linear-time RMQ can be used here. Are you talking about 2D static RMQ, or 1D dynamic, or some other version?

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

I believe it can be solved in O(nlog(n)^2) in the same manner as usual LIS but with constant less than in segment tree. Let dp[i] denote the set containing smallest elements where subsequence of length i could end(if we sort first elements in this set, the second elements will be anti-sorted).Now upper bound will work in the same manner instead of array of sorted elements d[i] we get array of sorted array sets. I am not sure about that:)

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

There was a comment that said this problem is similar to problem NICEDAY on spoj. But I can't see the similarity. Does anyone know how?