Quiz 2

Advanced Data Structures — Segment Trees, Fenwick Trees, Disjoint Sets

659 words
3 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Advanced Data Structures — Segment Trees, Fenwick Trees, Disjoint Sets ## 🎯 Learning Objectives - Build and query segment trees in O(log n) - Implement Fenwick tree for prefix sums - Apply DSU with union by rank and path compression - Solve range query problems with these structures * * * ## 1. Segment Tree ### 1...

Advanced Data Structures — Segment Trees, Fenwick Trees, Disjoint Sets

🎯 Learning Objectives

  • Build and query segment trees in O(log n)
  • Implement Fenwick tree for prefix sums
  • Apply DSU with union by rank and path compression
  • Solve range query problems with these structures

1. Segment Tree

1.1 Structure

Binary tree storing aggregate information (sum, min, max) for array segments. Array: [5, 3, 7, 9, 1, 6] Segment Tree (sum): Root = 31, children = [8, 23], etc. (Diagram)

1.2 Query: Range Sum [1, 4]

  1. Start at root [0-5]
  2. [0-5] partially overlaps → go to children
  3. [0-2] partially overlaps → go to children
  4. [0-1] partially → return right child [1] = 3
  5. [2] = 7 (fully covered)
  6. [3-5] partially → go to child [3-4] = 10 (fully covered)
  7. Result: 3 + 7 + 10 = 20

1.3 Time Complexity

OperationTime
BuildO(n)
QueryO(log n)
Point updateO(log n)
Range update (lazy)O(log n)

2. Fenwick Tree (Binary Indexed Tree)

2.1 Key Idea

Each index i stores sum of range (i - LSB(i) + 1, i], where LSB(i) = i & (-i). Fenwick tree for [5, 3, 7, 9, 1, 6]:
IndexValueLSBStores Range
151[1,1]
282[1,2]
371[3,3]
4244[1,4]
511[5,5]
672[5,6]

2.2 Query: Prefix Sum [1, 5]

  1. i=5: tree[5]=1, i=5-1=4
  2. i=4: tree[4]=24, i=4-4=0
  3. Result: 1 + 24 = 25 Update: Add v at position i: while i ≤ n: tree[i] += v; i += LSB(i)

3. Disjoint Set Union (DSU)

3.1 Path Compression + Union by Rank

python
class DSU:
    def __init__(self, n):
        self.parent = list(range(n))
        self.rank = [0] * n
    def find(self, x):  # Path compression
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    def union(self, x, y):  # Union by rank
        px, py = self.find(x), self.find(y)
        if px == py: return False
        if self.rank[px] < self.rank[py]:
            px, py = py, px
        self.parent[py] = px
        if self.rank[px] == self.rank[py]:
            self.rank[px] += 1
        return True

3.2 Tracing

Union(1, 2), Union(2, 3):
  • Initially: parent = [0,1,2,3], rank = [0,0,0,0]
  • Union(1,2): find(1)=1, find(2)=2, rank same, parent[2]=1, rank[1]=1
  • Union(2,3): find(2)→1, find(3)=3, rank[1]=1 > rank[3]=0, parent[3]=1 Complexity: O(α(n)) per operation (inverse Ackermann — practically constant)

4. Common Pitfalls

Pitfall: Fenwick Tree for Min/Max

The mistake: Using Fenwick tree for range minimum query (RMQ). Correct approach: Fenwick tree only works for prefix-able operations (sum, xor). For RMQ, use segment tree or Sparse Table.

5. Key Concepts Reference

StructureBuildQueryUpdateMemory
Segment TreeO(n)O(log n)O(log n)O(4n)
Fenwick TreeO(n log n)O(log n)O(log n)O(n)
DSUO(n)O(α(n))O(α(n))O(n)
Sparse TableO(n log n)O(1)N/AO(n log n)

6. 📝 Practice Questions

Q1: Build a segment tree for [2, 4, 1, 5, 3] for range sum.
Answer: Root (0-4): 15 Left (0-2): 7, Right (3-4): 8 (0-1): 6, (2): 1, (3): 5, (4): 3 (0): 2, (1): 4 Query [1, 3]: right child of (0-1)=4 + (2)=1 + (3)=5 = 10 Q2: Fenwick tree: prefix sum up to 6 for tree = [3, 7, 2, 12, 5, 9].
Answer: tree indices: 1=3, 2=7, 3=2, 4=12, 5=5, 6=9. prefix(6)=tree[6]+tree[4]=9+12=21. Verify: array = [3, 4, 2, 3, 5, 4]? Wait, Fenwick stores differently. tree[2]=7 means arr[1]+arr[2]=7. Let me verify: if tree = [3,7,2,12,5,9], then prefix(6)=tree[6]+tree[4]=9+12=21. prefix(5)=tree[5]+tree[4]=5+12=17. Q3: DSU: find operation with path compression. Explain the effect.
Answer: After find(x), every node on the path from x to the root has its parent set directly to the root. Future finds for these nodes are O(1). Without path compression, find could be O(n) for a chain. Combined with union by rank, the amortized time is O(α(n)) — practically constant even for n = 10^600.

7. 🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.