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

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

Hello everyone!

My friend and I were discussing range update and range query of maximum in two dimensions and I am not sure how to implement such a data structure. It appears to be much more difficult than range query/update in one dimensions as it is hard to propagate a tree.

Can anyone provide any insight on this?

Thanks in advance

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

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

It's impossible to achieve log^2 worst case time complexity. But you can use quad tree instead, which gives O(N) per update/query.

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

Hi !

Problem Tetris 3D require a 2D segment tree with update and query on range (it is what you need).

It is possible !

We need 2 segment tree (one main and other for lazy propagation) that every node of this segment trees has 2 segment trees; one main and other for lazy propagation.

It has a log^2 worst case time complexity.

See my code for better understanding.

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

    I've inspected your code:

    1. There's no lazy propagation. Lazily building tree is not the thing.
    2. The problem you deal with is specific: it is range max with strictly increasing overwrites. That's the reason your code safely overwrites aggregated values and never has to push delayed operations.
    • »
      »
      »
      6 лет назад, скрыть # ^ |
      Rev. 3  
      Проголосовать: нравится +23 Проголосовать: не нравится

      How exactly is this specific? It seems to me that it fully solves the problem of:

      • updating $$$M(x, y) = max(M(x, y), v)$$$ for all $$$(x, y)$$$ in some rectangle
      • querying the maximum of $$$M(x, y)$$$ for all $$$(x, y)$$$ in some rectangle

      If you mean that the updates have to come with increasing values of $$$v$$$, I think you're wrong (or at least, it seems to work ok to me for arbitrary $$$v$$$).

      Moreover, it seems that a lot of modifications are possible, including rectangle add value + rectangle sum query, which I for once thought to be very hard, if not impossible. Also, it seems to be able to be adapted easily to $$$x, y \leq 10^9$$$, which is just WOW.

      Not to mention that it seems that it can naturally be extended to an arbitrary number of dimensions (in complexity $$$O(log^D(MAX))$$$).

      I think this is an awesome technique, and it fully deserves to be appreciated.

      Fun fact: it uses the technique of "lazy without propagation" that I've described here some time ago, which, ironically, a handful of people (me included) thought that it wasn't that useful, along with the awesome observation that you can update a node in a segment tree without having to "combine" information from the two children (which would be impossible in 2D). These two things seem to allow 2D segment trees that can do a lot of the "lazy propagation" operations.

      [UPDATE] Found a paper: https://arxiv.org/pdf/1811.01226.pdf

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

        It's inaccurate for the paper to claim that it "is capable of performing any general aggregate function similar to the original Segment Tree" :/

        it seems that a lot of modifications are possible, including rectangle add value + rectangle sum query, which I for once thought to be very hard, if not impossible.

        Solving rectangle add value + rectangle sum query has been mentioned several times though:

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

          The first link gives me 404.

          The second link seems to describe fenwick trees with the linear function trick which is not trivial at all to implement for some people (I’ve never implemented myself the 1D version of it, as it feels too sketchy, compared to segment tree). Also, I would rather pick 2D segment trees than 2D BITs for inputs with higher coordinates (as 2D BIT with hash map would probably be very slow).

          The last comment does indeed describe this technique, but IMHO it’s still not convincing enough that people actually know about this idea.

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

        It is specific in the way you've described: it works for $$$M(x, y) \leftarrow max(M(x, y), v)$$$, but doesn't seem to work for $$$M(x, y) \leftarrow v$$$. The former updates are monotone, the latter are not.

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

        By the way, I'm not saying that the technique is useless. It's just that we shouldn't call it "lazy propagation".

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

        I do recall the problem and it seemed quite particular (as in I think you were using the fact that updates are monotone). Either way, the only truly nice thing about it is that the query you perform is for a non-invertible operator, and therefore you have to build the maximum constructively.

        I'd be curious to see if any results are known about this sort of operators, but the paper seems to exemplify an approach for sums only, if I'm not mistaken (and well other operators alike).

        Invertible, associative and commutative operators should be super easy compared to this if you consider 2^D cases (for D the dimension of the problem) on both updates and queries and some formulas here and there.

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

          I might be missing something here, but how exactly are invertible, associative and commutative operators super easy? Do you refer to using 3 2D fenwick trees?

          This approach seems to work with arbitrary non-invertible operators, as long as they are associative and commutative (on all axes). Setting a value is non-commutative, therefore it doesn’t work.

          Just to be clear, the problem here is solving (online):

          • $$$Update(rect, v)$$$ that does $$$M(x, y) \leftarrow M(x, y) \text{ op } v$$$ for $$$(x, y) \in rect$$$;
          • $$$Query(rect)$$$ that reduces $$$M(x, y)$$$ for $$$(x, y) \in rect$$$ using the operator $$$\text{op}$$$.