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

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

I am trying to learn 2D Segment trees, and I'm having problems implementing it. Especially when there are 2 points with same y-coordinate. Actually, the approach is to make a segment tree on the x-coordinates, and for the node with x-range [x1,x2] keep a segment tree with all y such that there exists a point (X,y) with x1<=X<=x2. Now suppose we have to update points and find maximums in a rectangle. So if I have to update point (X,Y), I go to the leaf with range [X,X], update the Y in its segment tree. But if I then come up to the parent, and try to update Y in its seg tree too, then I won't make any difference between two different points in that range with same y-coordinate Y. Please tell me if I'm incorrect, and correct me. And please provide me with a clean implementation of 2D segment trees, if you can.

If you want a clean formulation, here it is:

Given N (N<10^5) points each with an associated value, and Q queries (Q<10^5), each either a query or an update. The update operation gives you x,y,k and asks you to update the value at point (x,y) to k. The query operation gives you x1,y1,x2,y2 and asks you for the maximum in the rectangle (x1,y1)-(x2,y2). The update points are among the initially given points.

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

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

Yep, you don't make any difference between points with the same Y in each node of the outer tree, because you don't have to. If you ask some inner tree something, then it's clear that L ≤ l ≤ r ≤ R, where [L, R] is the query and [l, r] is the X-segment that the inner tree is responsible for.

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

    Suppose you have two points (x1,y) and (x2,y). Let the value at point (X,Y) be denoted by V[X,Y]. Let V[x1,y] > V[x2,y] initially. So in the segment tree for the node with range [x1,x2] (assume that it exists), for the y-coordinate you have stored V[x1,y]. But now you update V[x1,y] so that V[x1,y] < V[x2,y]. Then how will you update y-coordinate in this node ([x1,x2] in outer segtree)? You hadn't kept track of V[x2,y] , but now its the maximum !

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

      Oh, I see, I'm sorry. There's a problem with formal definition of what the inner tree should do. In fact, it should be able to store several values for each Y. It can be achieved by storing multiset or something similar in each leaf node and then considering its value as maximum of elements in the multiset. It's still lograthmic time.

      Does that make sence?

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

Let us start with an example. Suppose both coordinates are from 0 to 3. Then, if you add a point (1, 2), you add 1 point to the counts in the following vertices:

([1, 1], [2, 2]), ([0, 1], [2, 2]), ([0, 3], [2, 2]),
([1, 1], [2, 3]), ([0, 1], [2, 3]), ([0, 3], [2, 3]),
([1, 1], [0, 3]), ([0, 1], [0, 3]), ([0, 3], [0, 3]).

As you can see, each vertex has two coordinates: the binary segments it covers by x and by y.

A simple operation on a two-dimensional segment tree is usually along the lines of:

for (x-segment)
  for (y-segment)
    visit vertex (x-segment, y-segment)

Or, if you need the recursive version, you can define two functions. The x-recursion (x-segment) descends by x-segment and always calls the y-recursion from the top. The y-recursion (x-segment, y-segment) keeps x-segment constant, descends by y-segment and visits the actual vertex (x-segment, y-segment).

See e-maxx.ru for some example code (and an explanation that may be Google-translatable).

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

    Tried to translate e-maxx.ru, Google Translate didn't quite work. Thanks for explaining with an example. I needed an example. :D

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