Lecture 11: Binary jumping, Digit DP Henry Xia, Brandon Zhang based on CPSC 490 slides from 2014-2018 2019-02-07 University of British Columbia CPSC 490: Problem Solving in Computer Science
1 Range-minimum query Given an array A of N ≤ 10 6 numbers, answer Q ≤ 10 6 queries of the form “What is the minimum number in the subarray A [ l .. r ] ?”
Let’s try doing some computations to help us out. We need to “jump” by a lot when computing the min, if we want to do it fast. Let’s jump by powers of 2! 2 Range-minimum query Naive solution: O ( NQ ) . Too slow!
Let’s try doing some computations to help us out. We need to “jump” by a lot when computing the min, if we want to do it fast. Let’s jump by powers of 2! 2 Range-minimum query Naive solution: O ( NQ ) . Too slow!
3 largest integer such that 2 q O 1 per query! . 1 q 2 q f r f l q 1. The answer is l r How do we handle queries? If we need to find the minimum element of A l r , let q be the Recursive case: otherwise Binary jumping f ( i , p ) = the minimum number in A [ i .. i + 2 p − 1 ] . Base case: f ( i , 0 ) = A [ i ] . { i + 2 p < n min { f ( i , p − 1 ) , f ( i + 2 p , p − 1 ) } f ( i , p ) = f ( i , p − 1 ) Computing this table takes O ( N log N ) .
Recursive case: otherwise 3 Binary jumping f ( i , p ) = the minimum number in A [ i .. i + 2 p − 1 ] . Base case: f ( i , 0 ) = A [ i ] . { i + 2 p < n min { f ( i , p − 1 ) , f ( i + 2 p , p − 1 ) } f ( i , p ) = f ( i , p − 1 ) Computing this table takes O ( N log N ) . How do we handle queries? If we need to find the minimum element of A [ l .. r ] , let q be the largest integer such that 2 q ≤ r − l + 1. The answer is min { f ( l , q ) , f ( r − 2 q + 1 , q ) } . O ( 1 ) per query!
the lowest common ancestor of nodes u and v ”? 4 Lowest common ancestor Given a tree with N ≤ 10 5 nodes, how can we answer Q ≤ 10 5 queries of the form “What is
There are many ways to do this, but this binary jumping-based solution generalizes well to many problems! ancestor of u (2 k th node on the path from u to the root). First, let’s figure out how to compute these: 5 Lowest common ancestor We’ll store depth ( u ) = number of nodes on the path to the root, and par ( u , k ) = the 2 k th depth ( root ) = 0, depth ( u ) = depth ( parent ( u )) + 1 par ( u , 0 ) = parent ( u ) , par ( u , k ) = par ( par ( u , k − 1 ) , k − 1 )
Given this information how do we compute the LCA of u and v ? the largest k so that we don’t jump up above v . • Otherwise, jump up to the LCA: now that u and v are at equal depth, iteratively 6 Lowest common ancestor depth ( u ) = # of nodes on the path to the root par ( u , k ) = the 2 k th ancestor of u • Move up the deeper node: if u is deeper, then iteratively replace u ← par ( u , k ) for • At this point, if u = v then we’re done. replace u ← par ( u , k ) , v ← par ( v , k ) for the largest k such that par ( u , k ) ̸ = par ( v , k ) . • The LCA is parent ( u ) ( = parent ( v ) ). Runtime: O (log N ) per query.
7 6 12 11 10 9 8 1 7 5 4 2 3 Lowest common ancestor def lca(u, v): if depth[u] < depth[v]: swap u and v for k = log N .. 0: if depth[u] - 2 k >= depth[v]: u = par[u][k] if u == v: return u for k = log N .. 0: if par[u][k] != par[v][k]: u = par[u][k], v = par[v][k] return par[u][0]
Why consider LCA at all? We can answer many difgerent kinds of path queries using this technique! 8 Lowest common ancestor If we want the path from u to v , it is exactly the path u ↗ lca ( u , v ) ↘ v .
and v ?” 9 Problem 1 – Path lengths Input : a tree with N ≤ 10 5 nodes. Output : answer Q ≤ 10 5 queries of the form “What is the length of the path between u
Binary jumping! DP states: Recurrence: Answer: whenever we make a jump in our LCA-finding algorithm, also add the corresponding dist value to the total path length. 10 Problem 1 – Solution • par ( u , k ) = 2 k th ancestor of u • dist ( u , k ) = length of the path between u and its 2 k th ancestor • par ( u , k ) : same as before ( par ( u , 0 ) = parent ( u ) , par ( u , k ) = par ( par ( u , k − 1 ) , k − 1 ) ) • dist ( u , 0 ) = c ( u , parent ( u )) , dist ( u , k ) = dist ( u , k − 1 ) + dist ( par ( u , k − 1 ) , k − 1 ) Time complexity: O (( N + Q ) log N )
edges, find the path from u to v such that the minimum edge weight is maximized. 11 Problem 2 – Maximum bandwidth, revisited Recall the maximum bandwidth problem: given a graph on N ≤ 10 5 nodes and M ≤ 10 5 Now, answer Q ≤ 10 5 queries of this form!
Use binary jumping on this tree, similarly to the last problem! Remember that to solve this problem, we found the MST and used paths on that tree. 12 Problem 2 – Solution Time complexity: O ( M log M + ( N + Q ) log N )
Source: USACO Platinum December 2015 13 Problem 3 – Path counting Input : a tree on N ≤ 10 5 nodes, and M ≤ 10 5 special paths on the tree between u i and v i . Output : the node that is on the maximum number of special paths.
First, let’s consider the case where the tree is a stick. Store a value at each node which is the number of special paths it’s on. For a special u - v -path, let’s add 1 to each of the nodes on the path between u and v , then get the node with the maximum value. But this is too slow... Observation: we can “accumulate” values from bottom to top. • Store an extra amount at each node u which will be the amount the value changes 14 Problem 3 – Solution from the child ( u ) to u . • For a u - v -path (assuming u is deeper), add + 1 to u ’s amount and add − 1 to parent ( v ) ’s amount. • The value at a node u is then value ( child ( w )) + amount ( w ) .
• Do the same accumulation, going from the deepest nodes to the root. Now for a general tree... 15 Problem 3 – Solution • Our paths now go u ↗ lca ( u , v ) ↘ v . Split this into two paths u → lca ( u , v ) , v → lca ( u , v ) . • Add + 1 to u ’s amount and v ’s amount, add − 1 to lca ( u , v ) ’s amount, and add − 1 to parent ( lca ( u , v )) ’s amount. Time complexity: O (( N + M ) log N )
some property”. N may be very large (say, up to 10 100 ). using a DP. DP idea: we’ll build numbers satisfying the conditions digit by digit. 16 Digit DP We’ll answer the question “Count the number of integers 0 ≤ x ≤ N such that x satisfies As an example, let’s answer the trivial question “Count the number of integers 0 ≤ x ≤ N ”
0 f digit 17 1 digits . Time complexity: O Answer: f 0 0 . 0 less 1 1 f digit 0 i 1 N digit 1 0 f digit less 1 1 i 9 f digit less less accordingly. For the recursive case, try placing all possible digits at the current position and update 1. 1 less of digits Base case: f less is 0), the first digits of x match the first digits of N . less is 1 if we chose the first few digits of x so that it’ll be strictly less than N . Otherwise (if Counting numbers DP state: f ( digit , less ) = # of ways to choose the digits digit , digit + 1 , . . . , (# of digits ) of x such that 0 ≤ x ≤ N .
17 Answer: f 0 0 . digits . less is 1 if we chose the first few digits of x so that it’ll be strictly less than N . Otherwise (if less is 0), the first digits of x match the first digits of N . Time complexity: O For the recursive case, try placing all possible digits at the current position and update less accordingly. Counting numbers DP state: f ( digit , less ) = # of ways to choose the digits digit , digit + 1 , . . . , (# of digits ) of x such that 0 ≤ x ≤ N . Base case: f (# of digits + 1 , less ) = 1. {∑ 9 i = 0 f ( digit + 1 , 1 ) less = 1 f ( digit , less ) = f ( digit + 1 , 0 ) + ∑ N [ digit ] − 1 f ( digit + 1 , 1 ) less = 0 i = 0
17 For the recursive case, try placing all possible digits at the current position and update less accordingly. less is 1 if we chose the first few digits of x so that it’ll be strictly less than N . Otherwise (if less is 0), the first digits of x match the first digits of N . Counting numbers DP state: f ( digit , less ) = # of ways to choose the digits digit , digit + 1 , . . . , (# of digits ) of x such that 0 ≤ x ≤ N . Base case: f (# of digits + 1 , less ) = 1. {∑ 9 i = 0 f ( digit + 1 , 1 ) less = 1 f ( digit , less ) = f ( digit + 1 , 0 ) + ∑ N [ digit ] − 1 f ( digit + 1 , 1 ) less = 0 i = 0 Answer: f ( 0 , 0 ) . Time complexity: O (# digits ) .
times. 18 Problem 4 – Digit counting Given N ≤ 10 100 , count the integers 0 ≤ x ≤ N where the digit d ̸ = 0 appears exactly k
digits 2 . 19 1 less k Time complexity: O Answer: f 0 0 0 . position. Recurrence: same as before, but add 1 to count if we put the digit d in the current 1. of digits 0, f k 1 less i of digits Base case: f number of digits we’ve already set that are equal to d . Problem 4 – Solution DP state: f ( digit , less , count ) where digit and less are the same as before, and count is the
digits 2 . number of digits we’ve already set that are equal to d . Recurrence: same as before, but add 1 to count if we put the digit d in the current position. Answer: f 0 0 0 . Time complexity: O 19 Problem 4 – Solution DP state: f ( digit , less , count ) where digit and less are the same as before, and count is the Base case: f (# of digits + 1 , less , i ̸ = k ) = 0, f (# of digits + 1 , less , k ) = 1.
Recommend
More recommend