Segment Tree Flashcards

1
Q

Dynamic Range Minimum Query
* Add(i, v) A[i] += v
* RMQ(i, j) returns the position of the minimum element in A[i, …, j]

Solution with Segment Tree

A

Store in each node the minimum element of the segment and its position

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Dynamic RMQ with occurrences
* Add(i, v) A[i] += v
* Query(i, j) returns the position of the minimum element in A[i, …, j] and its number of occurrences

Solution with Segment Tree

A

Store in each node the minimum element of the segment and its number of occurrences

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Shortest prefix higher than a value
* Add(i, v) A[i] += v
* Query(s) search for the shortest prefix of A, say i, such that the sum of the elements A[1, …, i] is higher than s

Solution with Segment Tree

A

Store in each node the sum of the elements of the segment.

For each node, if value v at left child >= s, go left, otherwise s -= v and go right

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Position of the k-th 0
Given binary array A[0, n-1]
* Add(i, v) A[i] += v
* Select(k) reports the position of the k-th occurrence of 0

Solution with Segment Tree

A

Store in each node the number of zeroes in the segment.

For each node, if value v at left child >= k, go left, otherwise k -= v and go right

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Position of the k-th 0 in subarray A[i, …, j]
Given binary array A[0, n-1]
* Add(i, v) A[i] += v
* SelectHard(i, j, k) reports the position of the k-th occurrence of 0 in subarray A[i, …, j]

Solution with Segment Tree

A

Note: SelectHard is equal to Select(k + Sum(i-1)) where Sum(i-1) is the number of 0 in the prefix A[0, i-1]

Store in each node the number of zeroes in the segment.

For each node, if value v at left child >= k, go left, otherwise k -= v and go right

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Number of occurrences of X in subarray A[i, …, j]
Given array A[0, n-1]
* Add(i, v) A[i] += v
* Occs(i, j, x) reports number of occurrences of x in subarray A[i, …, j]

Solution with Segment Tree

A

Store in each node the set of distinct values in the segment with their number of occurrences.

You can use BBST, so for logn node we spend Θ(logn) time for each note then Θ(log^2 n) is the overall time

Space complexity: every value of A is stored in at most logn nodes. Overall space is nlogn

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Successor in subarray A[i, …, j]
Given array A[0, n-1]
* Add(i, v) A[i] += v
* Succ(i, j, x) reports the successor of x in subarray A[i, …, j]

Solution with Segment Tree

A

Store in each node a BBST with the set of distinct values in the segment. The answer is the min of the successor in each totally overlapping nodes.

Θ(log^2 n) query time. Can be improved with Fractional Cascading but it is not needed for the exam

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

k-th smallest element in subarray A[i, …, j]
Given (static) array A[0, n-1]
* Add(i, v) A[i] += v
* Smallest(i, j, k) reports the k-th smallest element in subarray A[i, …, j]

Solution with Segment Tree

A

Solve a easier query: Smallest(0, j, k) reports the k-th smallest in a prefix.
Assume values are in [0, n-1], if not remap.

Store in STj the occurrences of all the appearing numbers in A[0, j] then perform Smallest(0, j, k) on STj (search the position where prefix sum is greater than k).

Because we need n segment trees, use persistency by adding the occurrence of value A[j] at time j.

The general Smallest(i, j, k) query would need STij. Each node Uij of STij can be computed on-the-fly with the node Ui from STi and the node Uj from STj:
Uij = Uj - Ui

Θ(nlogn) space

Θ(logn) query time

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Triplets
Given A[0, n-1] with positive integers < n, count the number of triplets i,j,k (0 <=i < j < k <= n-1) such that

A[i] < A[j] < A[k]

Solution with Segment Tree

A

Assume values are in [0, n-1], if not remap.
Use two STs, one for the prefix and one for the suffix. STprefix is initialized to 0. Stsuffix is initialized to 1 in position A[i] for all i.

For all j
* RangeSum(A[j], n) on STsuffix gives the number of elements greater than A[j] and in pos k > j
* RangeSum(0, A[j]) on STprefix gives the number of elements lower than A[j] and in pos i < j
* Set to 1 the position j in STprefix and set to 0 the position j in STsuffix

Θ(nlogn) query time

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Smaller value
Given A[0, n-1] positive integers < n. Solve m given count queries (offline)
* count(i, j, X) reports the number of k (i <= k <= j) such that A[k] <= X

A

Use persistent segment tree.
Process values of A in sorted order.
If A[k] = t, then set B[k]=1 at time t
count(i, j, X) = RangeSum(i, j) at time X

Θ((n+m)logn) query time

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Lazy Propagation

A

To update an interval we will keep 3 things in mind.

  1. If current segment tree node has any pending update, then first add that pending update to current node.
  2. If the interval represented by current node lies completely in the interval to update, then update the current node and update the lazy[] array for children nodes.
  3. If the interval represented by current node overlaps with the interval to update, then update the nodes as the earlier update function

Cases while updating:
1. Segment lies outside the query range: in this case, we can just simply return back and terminate the call.
2. Segment lies fully inside the query range: in this case, we simply update the current node and mark the children lazy.
3. If they intersect partially, then we all update for both the child and change the values in them.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Persistent Segment Tree

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly