Using algorithm builtins
This guide covers the builtins that replace the most common copied contest templates.
Graphs
Section titled “Graphs”Create a graph, add edges, then call the algorithm you need.
g = graph(n) # directed, unweightedg = graph(n, undirected = true) # undirected, unweighted
wg = wgraph(n) # directed, weightedwg = wgraph(n, undirected = true) # undirected, weightedAdd edges:
g.add(u, v)wg.add(u, v, w)res = g.bfs(src)println res.dist[dst]res.dist[i] is -1 when i is unreachable.
Dijkstra
Section titled “Dijkstra”res = wg.dijkstra(src)println res.dist[dst] == INF ? -1 : res.dist[dst]0-1 BFS
Section titled “0-1 BFS”res = wg.zero_one_bfs(src)println res.dist[dst]Other graph helpers
Section titled “Other graph helpers”wg.bellman_ford(src) # distances + negative-cycle flagwg.floyd() # all-pairs shortest pathsg.topo() # topological orderg.scc() # strongly connected componentsg.bridges() # bridge edgesg.articulation_points() # articulation pointsg.bipartite() # 2-coloring or failure markerg.bipartite_matching(L) # maximum matching on [0, L) -> [L, n)wg.mst() # minimum spanning treeFor matching, keep the partition explicit:
res = g.bipartite_matching(L)println res.sizeprintln res.match_leftGrid graphs
Section titled “Grid graphs”input: R, C: int grid: matrix[char][R][C]
g = grid_graph(grid)Use 4 for orthogonal movement and 8 when diagonal moves are allowed.
The explicit form is grid_graph(grid, dirs = 8).
Binary search helpers
Section titled “Binary search helpers”Binary search on the answer
Section titled “Binary search on the answer”ans = bsearch(lo, hi, |mid| feasible(mid))This returns the first integer in [lo, hi] where the predicate is true.
ans = bsearch_last(lo, hi, |mid| can_keep(mid))This returns the last integer in [lo, hi] where the predicate is true.
Binary search in a sorted array
Section titled “Binary search in a sorted array”lower(a, x)upper(a, x)Use these after sorting an array when you need counts, insertion points, or range boundaries.
d = dsu(n)d.unite(u, v)d.same(u, v)d.find(u)d.size(u)d.components()Use DSU for connectivity under unions, Kruskal-style workflows, and component counting.
Tree helpers
Section titled “Tree helpers”t = tree(n)t.add(u, v)t.build(0)println t.lca(a, b)println t.dist(a, b)Use tree(...) when the input is a tree and you need LCA, distances, subtree sizes,
or ancestor jumps without pasting a binary-lifting template.
Segment tree
Section titled “Segment tree”st = segtree(n, op = max)st = segtree(a, op = sum)Supported reducers are sum, max, min, gcd, and prod.
st.update(i, val)st.query(l, r)Use a segment tree when you need point updates plus range queries.
Fenwick tree
Section titled “Fenwick tree”b = bit(n)b.add(i, val)b.sum(l, r)b.lower_bound(target)Use a Fenwick tree when you only need prefix/range sums with point updates.
Sparse table
Section titled “Sparse table”sp = sparse(a, op = min)sp.query(l, r)Use a sparse table for static arrays with idempotent operations such as min, max,
or gcd.
Choosing the right tool
Section titled “Choosing the right tool”- Graph shortest paths on unweighted edges:
bfs - Graph shortest paths on non-negative weighted edges:
dijkstra - Connectivity under unions:
dsu - Point updates + range queries:
segtree - Point updates + sum queries only:
bit - Static RMQ/GCD-style queries:
sparse