Skip to content

Working with arrays and containers

This guide covers the core collection features you will use in most algo programs.

Arrays map to C++ vectors.

a: [int]
b: [[int]]
dist: [long]

Create filled arrays with filled:

freq = filled(n, 0)
dist = filled(n, INF)
dp = filled(n + 1, filled(m + 1, 0))
sort(a)
sort(a, desc)
sort_by(a, key = |x| x.second)
best = min_by(a, key = |x| x.cost)
sort(a, |x, y| x.first < y.first)

Search helpers on sorted arrays:

lower(a, x)
upper(a, x)
a.sum()
a.min()
a.max()
a.count(|x| x > 0)
a.any(|x| x < 0)
a.all(|x| x > 0)
a.filter(|x| x > 0)
a.map(|x| x * 2)
a.find(|x| x > 0)
a.push(x)

Free-function forms exist too:

sum(a)
min(a)
max(a)
filter(a, |x| x > 0)
map(a, |x| x * 2)
sq = [x * x for x in a]
evens = [x for x in a where x % 2 == 0]
indices = [i for i in [0, n) where a[i] > 0]
pairs = [(i, a[i]) for i in [0, n)]

Use comprehensions when they make the new collection clearer than an explicit loop.

println max(dp[i] for i in [0, n))
println sum(a[i] * b[i] for i in [0, n))
ans = min(abs(a[i] - a[j]) for i in [0, n) for j in [0, n) where i != j)

Use reductions when you want one value from a collection or range.

reverse(a)
fill(a, val)
unique(a)
len(a)
b = a.compress()
a.sliding_max(k)
a.sliding_min(k)
a.next_greater()
a.next_smaller()
algoC++ shapeTypical use
set[T]hash setmembership checks
oset[T]ordered setordered membership
map[K, V]hash mapfrequency maps
omap[K, V]ordered mapordered key queries
multiset[T]multisetduplicates + ordering
pq[T]max-heapbest-first selection
pq[T, min]min-heapDijkstra / greedy
stack[T]stackLIFO
queue[T]queueBFS / FIFO
deque[T]dequedouble-ended access
s: multiset[int]
s.insert(x)
s.erase_one(x)
s.min()
s.max()
s.count(x)
q: pq[int]
q: pq[int, min]
q: pq[(long, int), min]
t = (dist[v], v)
(d, u) = t
for (u, v, w) in edges:
# ...
type Edge = pair[int, int]
type Adj = [[Edge]]

Use aliases when a container or tuple type is repeated enough to hurt readability.