synopsis · Expert · chapter 38
Segment Trees, Fenwick & String Matching
10 cards, about a minute. Read them the night before an interview, or right after the chapter to lock it in.
- what it is
Range queries: keep block sums so any range is a few blocks. Strings: never re-read matched text (KMP, Z), or compare cheap hashes first (Rabin–Karp).
- use it when
No updates → prefix sums. Point updates + sums → Fenwick. Min/max/gcd, or adds over a range → segment tree (+ lazy).
- template
Fenwick (1-based): update climbs
i += i & -i, query stripsi -= i & -i. Range sum =prefix(r + 1) - prefix(l). - template
Segment-tree query: no overlap → identity, full overlap →
tree[node], partial → both children (2*node,2*node+1). Allocate4 * n. - template
KMP: mismatch →
j = lps[j - 1](repeat); match →j++;j == m→ match ati - m + 1. The text index i never moves back. - cost
Fenwick and segment tree: O(log n) per update and query, O(n) memory. KMP and Z: O(n + m). Rabin–Karp: O(n + m) expected, O(n·m) worst.
- trap
Fenwick index 0 never moves (
0 & -0 == 0) — stay 1-based.updatesets a value: addval - nums[i], notval. - trap
Equal hashes are not equal strings: verify the characters, use
long, and addMODback after subtracting. - use it when
"How many smaller/greater values before or after i?" → compress values to ranks, walk once, count ranks with a Fenwick tree.
- pro tip
Stuck on a string problem? Glue strings —
p + '#' + t,s + s,s + '#' + reverse(s)— and run the prefix or Z function on the result.
Shaky on a card? Open the chapter or flip its recall cards.