Table of Contents
Segment TreeResourcesDynamic Range Minimum QueriesRecursive ImplementationIterative ImplementationDynamic Range Sum QueriesRecursive ImplementationIterative ImplementationBinary Indexed TreeResourcesDynamic Range Sum QueriesImplementationFinding the -th ElementOrder Statistic TreeWith a BITWith a Segment TreeInversion CountingImplementationProblemsGeneralUSACOMost gold range query problems require you to support following tasks in time each on an array of size :
- Update the element at a single position (point).
- Query the sum of some consecutive subarray.
Both segment trees and binary indexed trees can accomplish this.
Segment Tree
A segment tree allows you to do point update and range query in time each for any associative operation, not just summation.
Resources
You can skip more advanced applications such as lazy propagation for now. They will be covered in platinum.
| Resources | |||||
|---|---|---|---|---|---|
| CF EDU | basic operations, inversion counting | ||||
| CSA | Interactive updates. | ||||
| CPH | Same implementation as AICash below. | ||||
| CPC | See slides after union-find. Also introduces sqrt bucketing. | ||||
| cp-algo | "Advanced versions" are covered in Platinum. | ||||
| CF | simple implementation | ||||
| KACTL | similar to above | ||||
Dynamic Range Minimum Queries
Focus Problem – try your best to solve this problem before continuing!
Recursive Implementation
Time Complexity:
Warning!
Due to heavy recursion and function-call overhead, this implementation exceeds the time limit. To pass on CSES, use the iterative implementation or a faster language.
import mathfrom typing import List, Optionalclass MinSegmentTree:def __init__(self, arr: Optional[List[int]] = None, length: Optional[int] = None):self.DEFAULT = math.infif arr is None:self.n = lengthself.segtree = [self.DEFAULT] * (self.n * 4)
Iterative Implementation
Though less extensible, this implementation is shorter and has a better constant factor. The ranges it operates on are also end-exclusive, unlike the previous one which is end-inclusive.
Time Complexity:
class MinSegmentTree:"""A data structure that can answer point update & range minimum queries."""def __init__(self, len_: int):self.len = len_self.tree = [0] * (2 * len_)def set(self, ind: int, val: int) -> None:"""Sets the value at ind to val."""ind += self.len
Dynamic Range Sum Queries
Focus Problem – try your best to solve this problem before continuing!
Recursive Implementation
Time Complexity:
Warning!
This Python segment tree is too slow for CSES and will result in TIME LIMIT EXCEEDED due to heavy recursion and function-call overhead.
Use an iterative version or a faster language.
from typing import List, Optionalclass SumSegmentTree:def __init__(self, arr: Optional[List[int]] = None, length: Optional[int] = None):self.DEFAULT = 0if arr is None:self.n = lengthself.segtree = [self.DEFAULT] * (self.n * 4)else:
Iterative Implementation
Time Complexity:
Compared to the previous implementation, all we need to change is the way we
aggregate values (from min() to '+'), and change the initial value to 0.
Code Snippet: Segment Tree (Click to expand)arr_len, query_num = map(int, input().split())arr = list(map(int, input().split()))segtree = SumSegmentTree(arr_len)for i, v in enumerate(arr):segtree.set(i, v)
Binary Indexed Tree
The implementation is shorter than segment tree, but maybe more confusing at first glance.
Resources
| Resources | |||||
|---|---|---|---|---|---|
| CSA | interactive | ||||
| CPH | similar to above | ||||
| cp-algo | also similar to above | ||||
| TC | |||||
Dynamic Range Sum Queries
Implementation
class BIT:"""Short for "binary indexed tree",this data structure supports point update and range sumqueries like a segment tree."""def __init__(self, len_: int) -> None:self.bit = [0] * (len_ + 1)self.arr = [0] * len_
Finding the -th Element
Suppose that we want a data structure that supports all the operations as a
set in C++ in addition to the following:
order_of_key(x): counts the number of elements in the set that are strictly less thanx.find_by_order(k): similar tofind, returns the iterator corresponding to thek-th lowest element in the set (0-indexed).
Order Statistic Tree
Luckily, such a built-in data structure already exists in C++. However, it's only supported on GCC, so Clang users are out of luck.
| Resources | |||||
|---|---|---|---|---|---|
| CF | |||||
| CPH | brief overview with find_by_order and order_of_key | ||||
| KACTL | code | ||||
With a BIT
However, if all updates are in the range , we can do the same thing with a BIT.
| Resources | |||||
|---|---|---|---|---|---|
| CF | log N | ||||
With a Segment Tree
Covered in Platinum.
Inversion Counting
Focus Problem – try your best to solve this problem before continuing!
Implementation
Code Snippet: BIT (Click to expand)MAX_ELEM = 10**7test_num = int(input())for _ in range(test_num):bit = BIT(MAX_ELEM + 1)input()arr_len = int(input())
Problems
Coordinate Compression
If the coordinates are large (say, up to ), then you should apply coordinate compression before using a BIT or segment tree (though sparse segment trees do exist).
General
| Status | Source | Problem Name | Difficulty | Tags | ||
|---|---|---|---|---|---|---|
| CSES | Easy | Show TagsPURS | ||||
| Kattis | Easy | Show TagsInversions, PURS | ||||
| CSES | Easy | Show TagsPURS | ||||
| CSES | Easy | Show TagsCoordinate Compress, PURS | ||||
| CF | Easy | Show TagsBinary Search, Offline, PURS | ||||
| CSES | Easy | Show TagsCoordinate Compress, PURS | ||||
| CSES | Normal | Show TagsOffline, PURS | ||||
| CSES | Hard | Show TagsInversions, PURS | ||||
USACO
| Status | Source | Problem Name | Difficulty | Tags | ||
|---|---|---|---|---|---|---|
| Gold | Easy | Show TagsInversions, PURS | ||||
| Gold | Easy | Show TagsInversions, PURS | ||||
| Gold | Easy | Show TagsInversions, PURS | ||||
| Gold | Easy | Show TagsPURS | ||||
| Platinum | Easy | Show TagsInversions, PURS | ||||
| Old Gold | Hard | Show TagsPURS | ||||
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!