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

Автор Thrb_73, история, 2 месяца назад, По-английски

I was solving a problem where we have k intervals, and we need to count the number of nested pairs.

More formally, count pairs (i, j) such that:

l_i < l_j <= r_j < r_i

(or equivalently after sorting by the left endpoint, count previous intervals whose right endpoint is greater than or equal to the current one).

The standard solution is:

  1. Sort intervals by the left endpoint.
  2. Insert right endpoints into an ordered_set (PBDS).
  3. Use order_of_key() to count how many previous right endpoints are greater than or equal to the current one.

This gives an O(n log n) solution.

My question is:

Is there an O(n log n) or O(n) solution that does not use PBDS (ordered_set), GNU extensions, or similar policy-based data structures?

I'm looking for alternatives using only standard C++ (STL). Thanks!

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

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

Auto comment: topic has been updated by Thrb_73 (previous revision, new revision, compare).

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

Segment trees or Binary search trees can do that in O(nlogn).

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

Observe that any two segments can be either completely separate, partially overlapping (including sharing a border), or nested. For each segment $$$i$$$ only consider those that start strictly before it ends. Then the number of nested segments is those that end strictly before $$$r_i$$$ minus those that end strictly before $$$l_i$$$ and those that start before or at $$$l_i$$$ and end strictly before $$$r_i$$$.

  1. Do coordinate compression so $$$l_i,r_i\le 2n$$$. This takes $$$O(n\log n)$$$ time.

  2. For each $$$l$$$ and $$$r$$$ value, make a vector of the segments that start and end here, respectively. Call those $$$s_i$$$ and $$$t_i$$$ respectively.

  3. Iterate $$$i$$$ over the values from left to right while maintaining a running count of how many open segments there are and how many closed segments there are (both initially 0).

  4. At each value perform the following:

a. Store the open and closed running counts in $$$o_i$$$ and $$$c_i$$$, respectively.

b. Iterate $$$j$$$ through $$$t_i$$$ and add $$$c_{r_j}-c_{l_j}-o_{l_j}$$$ to the final answer.

c. Update the running counts by adding $$$|t_i|$$$ to the closed count and adding $$$|s_i|-|t_i|$$$ to the open count.