0% found this document useful (0 votes)
39 views

Segment Tree

The document describes using a segment tree to speed up range minimum queries (RMQ). It notes that a naive divide and conquer approach does not improve the runtime over the initial solution. It then makes two observations: 1) every recursive call will use one of the predefined subarrays, and 2) recursive calls on full arrays will make subcalls on full arrays. Based on this, it proposes precomputing the minimum of each possible subarray and storing it in a segment tree, allowing queries to be done in O(1) time by looking up the precomputed minimum.

Uploaded by

Victor Reyna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views

Segment Tree

The document describes using a segment tree to speed up range minimum queries (RMQ). It notes that a naive divide and conquer approach does not improve the runtime over the initial solution. It then makes two observations: 1) every recursive call will use one of the predefined subarrays, and 2) recursive calls on full arrays will make subcalls on full arrays. Based on this, it proposes precomputing the minimum of each possible subarray and storing it in a segment tree, allowing queries to be done in O(1) time by looking up the precomputed minimum.

Uploaded by

Victor Reyna
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

A Faster Approach: Segment Trees

A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
Base case:
A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
● Base case:
A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
● Base case:

● Recursive cases:
A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
● Base case:

● Recursive cases:
A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
● Base case:

● Recursive cases:
A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
● Base case:

● Recursive cases:
A Divide-and-Conquer Approach
● Idea: Use divide-and-conquer to speed
up RMQ calculations by splitting the
overall array in half at each point.
● Base case:

● Recursive cases:
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

313141 592626 535358 979793

31 41 59 26 53 58 97
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 585397 93

313141 592626 535358 979793

31 41 59 26 53 58 97
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 262653 58 97 93

31 412659 26 53 585397 93

313141 592626 535358 979793

31 41 59 26 53 58 97
A Divide-and-Conquer Approach

31 41 59 26 53 58 97 932623 84 62 64 33 83 27 95

31 41 59 262653 58 97 93

31 412659 26 53 585397 93

313141 592626 535358 979793

31 41 59 26 53 58 97
Analyzing Efficiency
● Each recursive call fires off at most two
recursive calls and does O(1) work to
combine them.
● Recurrence relation:
T(n) = 2T(n / 2) + O(1)
● Using the Master Theorem, this solves to
O(n).
● This is no better than our initial solution!
An Observation

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
An Observation

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

Observation
Observation1: 1:Every
Everyrecursive
recursive
call
callthat
thatwill
willever
everbe
bemade
madedoing
doing
RMQ
RMQthis thisway
waymust
mustuse
useone
oneofofthe
the
subarrays
subarraysgiven
givenhere.
here.
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97
A Second Observation

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93

Observation
Observation2: 2:When
Whenaa
31 41 59 26 53 58 recursive
97 93 call
recursive callisismade
madeononaa
full
fullarray,
array,its
itssubcalls
subcallswill
will
be
bemade
madeon onfull
fullarrays.
arrays.
31 41 59 26 53 58 97
A Revised Idea
● For each subarray that could ever be visited by a
recursive call, compute the minimum of that subarray
and store it.
● Store result as a segment tree:
26

26 53

31 26 53 93

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
● Can be built with O(n) preprocessing. (why)?
A Revised Idea
● Modify the recursive algorithm to use the
segment tree.
● If range to search equals the range at the
current node, return the minimum value in that
range.
● We precomputed this; takes time O(1).
● Otherwise:
● If range is purely in the first or second half, recurse
on that subrange.
● Otherwise, split the range in half, then recursively
search the left and right halves and take the
minimum.
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 41 59 26 53 58 97 93
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 58 97 93
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 58 97 93

53 58 97 93
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 58 97 93

535858 97 93
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 58 97 93

535858 97 93

97
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 58 97 93

535858 97 93

97
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 58 97 93

535858 979793

97
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 26 53 58 97 93

31 412659 26 53 585897 93

535858 979793

97
Segment Trees

31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 95

31 41 59 262653 58 97 93

31 412659 26 53 585897 93

535858 979793

97
Segment Trees

31 41 59 26 53 58 97 932623 84 62 64 33 83 27 95

31 41 59 262653 58 97 93

31 412659 26 53 585897 93

535858 979793

97
Is This Faster?
● The root cause of the inefficiency in the
initial approach was the branching
recursion, which is still present in this
new solution.
● Is this new approach any faster than
what we had before?
● Claim: Yes! In fact, queries only take
time O(log n).
An Observation
An Observation
An Observation
An Observation
An Observation

Claim
Claim1: 1:The
Thefirst
firsttime
time
the
therecursion
recursionsplits,
splits,itit
leaves
leavesbehind
behindtwo
two
ranges
rangesthat
thatare
areeach
each
flush
flushagainst
againstone
oneside
side
of
ofthe
thesubarray.
subarray.
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
Another Observation
● Suppose the RMQ is over a range that is
flush against one edge of the subarray.
● The recursion will then either
● immediately terminate, or
● recurse purely in one half of the subarray, or
● recurse in both halves, but one of the
recursive calls will immediately terminate.
● In this case, there is at most one “real”
recursive call.
The Final Analysis
● If the recursion never splits into two pieces, the
runtime is O(log n).
● If the recursion does split into two pieces:
● Up until the split, we only can do O(log n) work
because there is one recursive call per level.
● After the recursion splits, each of the two pieces will
have the “flush against the wall” structure and will
take time only O(log n).
● Total work done: O(log n).
● This is exponentially faster than before!
Segment Trees
● The segment tree approach requires O(n)
preprocessing and O(log n) time per query.
● We now have an ⟨O(n), O(log n)⟩ solution to
RMQ!
● To put that in perspective:
● If we make o(n2 / log n) queries, this is
asymptotically faster than precomputing
everything.
● If we make ω(1) “large” queries, this is
asymptotically faster than doing no
precomputation.

You might also like