← All problemsFree · Python · 50 min

Algorithm design / guarantees under an adversary

The Ledger of Ranges

Add to a whole range of accounts and total any range, thousands of times. Count how many tree nodes a range needs, then write lazy propagation on a segment tree whose every field read is counted.

0 / 3 graded parts passSaved in this browser · loading saved work…
Jump to your work ↓

A bank keeps n accounts in a row and must, many thousands of times, add x to every account in a range [l,r), or total a range. The figure shows its segment tree for 8 accounts holding 3,1,4,1,5,9,2,6, just after adding 2 to accounts 1 to 6.

43[0,8)15[0,4)6[0,2)3[0,1)3[1,2)9[2,4)+24[2,3)1[3,4)28[4,8)18[4,6)+25[4,5)9[5,6)10[6,8)4[6,7)6[7,8)
Each node shows its sum and its range. The four pieces of [1, 7) are outlined; the tags +2 are adds still owed to the children.

The two requests are:

  • add(l, r, x): add x to every account i with l≤i<r (interest, fees, corrections);
  • total(l, r): the sum of accounts l to r−1.

A segment tree stores the sum of every range [lo,hi) that halving produces. The root is [0,n), and a node with more than one account has children [lo,mid) and [mid,hi), where mid=⌊(lo+hi)/2⌋. Any range [l,r) is the union of a few nodes, its pieces: the nodes where a walk from the root stops because they lie wholly inside the range. A total reads its pieces. An add that updated every account would be slow, so it leaves a tag, "+x for everything below", on its pieces instead. This is lazy propagation.

In the figure, add(1, 7, 2) had the pieces [1,2), [2,4), [4,6) and [6,7), and only the two pieces with children carry the tag.

Background: Range Queries and Segment Trees.

easy · Part A

Pieces of one range

In the segment tree over 16 accounts, how many pieces does the range [1,15) split into?

Explore in the sandbox

Experiment here, then copy a rule into the editor and test its guarantees.