ecpc_reference
ecpc_reference
Adham
Contents
0. How To Use This Book 4
1. C++ / STL Essentials 5
Fast I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Template header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
set / map / unordered_map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
priority_queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
deque / stack / queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
lower_bound / upper_bound (sorted range required!) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Custom comparator / lambda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
bitset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Useful one-liners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4. Binary Search 10
Binary Search on Answer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Finding rst / last valid index with a predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5. Number Theory 11
GCD / LCM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Extended GCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Sieve of Eratosthenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Smallest Prime Factor (fast factorization) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Prime factorization (no sieve, O(sqrt n)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Divisors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Modular Arithmetic & Fast Exponentiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Euler's Totient phi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Combinations mod p (precompute factorials) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Pascal's Triangle (small n, no mod inverse needed) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Chinese Remainder Theorem (two congruences) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Bit tricks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6. Recursion / Backtracking 14
Subsets (bitmask) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Subsets (recursive) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1
ECPC Team Reference 2
Permutations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Combinations (choose r of n) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
N-Queens pattern (placement with constraint sets) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Meet in the Middle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Pruning techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7. Graphs 16
Adjacency List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
BFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
DFS (iterative & recursive) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Connected Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Grid BFS/DFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Bipartite Check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Cycle Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Topological Sort (Kahn's algorithm) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
DSU (Disjoint Set Union) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Kruskal's MST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Prim's MST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Dijkstra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
0-1 BFS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Bellman-Ford . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Floyd-Warshall (all pairs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Strongly Connected Components (Kosaraju) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Bridges & Articulation Points (Tarjan) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Euler Path / Circuit (Hierholzer) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
8. Trees 21
Tree DFS + Subtree Sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Tree Diameter (2 BFS/DFS passes) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
LCA via Binary Lifting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Tree DP (basic, e.g. max independent set) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Rerooting Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
9. Data Structures 23
Fenwick Tree (Binary Indexed Tree) point update, prex sum . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Segment Tree (point update, range sum) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Lazy Segment Tree (range update, range sum) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Sparse Table (static range min/max/gcd, O(1) query) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Monotonic Stack (next greater element) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Monotonic Queue (sliding window minimum) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Trie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
11. Strings 28
Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Frequency count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Palindrome check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
String Hashing (polynomial rolling hash) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
KMP (pattern matching, O(n+m)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
ECPC Team Reference 3
Z-function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Manacher's Algorithm (longest palindromic substring, O(n)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Aho-Corasick (multi-pattern matching) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
12. Greedy 31
Sorting-based Greedy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Interval Scheduling (max non-overlapping intervals) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Activity Selection / Minimum Rooms (interval overlap count) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Exchange Argument (intuition) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Common Min/Max Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
13. Geometry 32
Point / Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Dot Product & Cross Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Orientation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Distance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Line / Segment Intersection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Polygon Area (Shoelace formula) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Convex Hull (Andrew's monotone chain) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Template header
#include <bits/stdc++.h>
using namespace std;
#define int long long // careful: changes behavior of int-sized things globally
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define all (x) (x).begin(), (x).end()
#define pb push_back
const int MOD = 1e9+7;
vector
vector<int> v = {1,2,3};
v.push_back(4);
v.pop_back();
[Link]([Link]()+1, 99); // insert at index 1
[Link]([Link]()+1); // remove index 1
sort(all(v));
reverse(all(v));
[Link](10, 0);
Trap: unordered_map can be attacked with anti-hash tests -> use a custom hash or gp_hash_table if TLE on Codeforces.
priority_queue
priority_queue<int> maxheap; // max-heap default
priority_queue<int, vector<int>, greater<int>> minheap; // min-heap
priority_queue<pii, vector<pii>, greater<pii>> pq; // min-heap of pairs (dist, node)
bitset
bitset<32> b(13); // 00000000000000000000000000001101
[Link](0); [Link](1); [Link](2);
[Link](); // number of set bits
b.to_ullong();
Useful one-liners
iota(all(v), 0); // fill 0,1,2,...
__builtin_popcount(x); // int popcount
__builtin_popcountll(x); // long long popcount
__builtin_clz(x); __builtin_ctz(x); // leading / trailing zeros
*max_element(all(v)); *min_element(all(v));
accumulate(all(v), 0LL);
unique(all(v)); // removes consecutive dups -> sort first, then [Link](unique(all(v)),
,→ [Link]())
next_permutation(all(v));
__gcd(a,b);
ECPC Team Reference 7
n Expected complexity
<= 10 O(n!) or O(2n * n)
<= 20 O(2n) bitmask DP/backtracking
<= 500 O(n3)
<= 5,000 O(n2)
<= 1e5 - 2e5 O(n log n)
<= 1e6 - 1e7 O(n) or O(n log n) tight
<= 1e9 O(log n) or O(sqrt n)
huge (1e18) O(1) / O(log n) formula, matrix expo
Pattern triggers: - Values huge but few distinct / few operations -> coordinate compression. - Subarray sum / range
sum, static array -> prex sums. - Range sum, updates too -> Fenwick / segment tree. - Min/max sum of contiguous
subarray -> Kadane. - Count pairs with property, sorted-able -> two pointers or binary search. - Optimal choice,
greedy fails on samples -> probably DP. - n <= 20, subsets -> bitmask DP. - String matching -> KMP / Z-function
/ hashing. - Shortest path -> see table in Section 7. - Connectivity / grouping -> DSU or BFS/DFS. - Min spanning
structure -> Kruskal/Prim (MST) or DSU. - Optimize over a monotonic function of the answer -> binary search on
answer. - Grid problem, small grid -> BFS/DFS/DP on grid. - Interval scheduling -> sort + greedy. - Tree, queries
about ancestor/depth -> LCA / binary lifting. - XOR / independent choices game -> Sprague-Grundy / game theory.
ECPC Team Reference 8
3. Arrays
Prex Sum
vector<long long> pre(n+1, 0);
for (int i = 0; i < n; i++) pre[i+1] = pre[i] + a[i];
// sum of [l, r] inclusive, 0-indexed:
long long rangeSum = pre[r+1] - pre[l];
2D Prex Sum
vector<vector<long long>> pre(n+1, vector<long long>(m+1, 0));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
pre[i][j] = a[i-1][j-1] + pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1];
// sum of rectangle (r1,c1)-(r2,c2), 0-indexed inclusive:
long long rect = pre[r2+1][c2+1] - pre[r1][c2+1] - pre[r2+1][c1] + pre[r1][c1];
Two Pointers
// e.g. count pairs with a[i]+a[j] <= x in sorted array
sort(all(a));
int l = 0, r = n-1; long long cnt = 0;
while (l < r) {
if (a[l] + a[r] <= x) { cnt += r - l; l++; }
else r--;
}
Coordinate Compression
vector<int> vals = a;
sort(all(vals)); [Link](unique(all(vals)), [Link]());
auto comp = [&](int x){ return lower_bound(all(vals), x) - [Link](); };
ECPC Team Reference 10
4. Binary Search
// Standard binary search for exact value in sorted array
int lo = 0, hi = n-1, ans = -1;
while (lo <= hi) {
int mid = lo + (hi-lo)/2;
if (a[mid] == target) { ans = mid; break; }
else if (a[mid] < target) lo = mid+1;
else hi = mid-1;
}
Common predicates: can we nish within time T, is capacity C enough, is answer >= x achievable.
ECPC Team Reference 11
5. Number Theory
GCD / LCM
long long gcd(long long a, long long b) { return b ? gcd(b, a%b) : a; }
long long lcm(long long a, long long b) { return a / gcd(a,b) * b; }
// C++17 has __gcd(a,b) built in
Extended GCD
long long extgcd(long long a, long long b, long long &x, long long &y) {
if (!b) { x = 1; y = 0; return a; }
long long x1, y1;
long long g = extgcd(b, a%b, x1, y1);
x = y1; y = x1 - (a/b)*y1;
return g;
}
Sieve of Eratosthenes
vector<bool> isComposite(N+1, false);
vector<int> primes;
for (int i = 2; i <= N; i++) {
if (!isComposite[i]) primes.push_back(i);
for (int p : primes) {
if ((long long)i*p > N) break;
isComposite[i*p] = true;
if (i % p == 0) break;
}
}
Divisors
vector<long long> divisors(long long n) {
vector<long long> d;
for (long long i = 1; i*i <= n; i++) {
if (n % i == 0) { d.push_back(i); if (i != n/i) d.push_back(n/i); }
}
return d;
}
}
return C;
}
Bit tricks
x & (x-1) // remove lowest set bit
x & (-x) // isolate lowest set bit
x | (x-1) // set all bits below lowest set bit
(x >> k) & 1 // check bit k
x = (1 << k) // toggle bit k
ECPC Team Reference 14
6. Recursion / Backtracking
Subsets (bitmask)
for (int mask = 0; mask < (1 << n); mask++) {
vector<int> subset;
for (int i = 0; i < n; i++) if (mask & (1 << i)) subset.push_back(a[i]);
// process subset
}
Subsets (recursive)
void gen(int i, vector<int>& cur) {
if (i == n) { /* process cur */ return; }
gen(i+1, cur); // exclude a[i]
cur.push_back(a[i]);
gen(i+1, cur); // include a[i]
cur.pop_back();
}
Permutations
vector<int> a = {1,2,3};
sort(all(a));
do {
// process permutation a
} while (next_permutation(all(a)));
Combinations (choose r of n)
void comb(int start, vector<int>& cur, int r) {
if ((int)[Link]() == r) { /* process cur */ return; }
for (int i = start; i < n; i++) {
cur.push_back(a[i]);
comb(i+1, cur, r);
cur.pop_back();
}
}
solve(row+1);
cols[c] = diag1[row+c] = diag2[row-c+n] = false;
}
}
Pruning techniques
Sort input rst so bad branches die early.
Track a running bound (best-so-far) and cut when it can't beat it.
Memoize repeated states (turns backtracking into DP).
Order choices smartest-rst (most constrained variable).
ECPC Team Reference 16
7. Graphs
When do I use which shortest-path algorithm?
Situation Algorithm
Unweighted BFS
Weights are only 0 or 1 0-1 BFS (deque)
Positive weights Dijkstra
Negative edges, no negative cycle Bellman-Ford
All-pairs, small n (<= 500) Floyd-Warshall
DAG DP over topo order
Adjacency List
vector<vector<int>> adj(n); // unweighted
adj[u].push_back(v); adj[v].push_back(u); // undirected
BFS
vector<int> dist(n, -1);
queue<int> q;
dist[src] = 0; [Link](src);
while (![Link]()) {
int u = [Link](); [Link]();
for (int v : adj[u]) if (dist[v] == -1) { dist[v] = dist[u]+1; [Link](v); }
}
Connected Components
int components = 0;
vector<int> comp(n, -1);
for (int i = 0; i < n; i++) {
if (comp[i] == -1) {
// BFS/DFS from i, label every reached node with `components`
components++;
}
}
ECPC Team Reference 17
Grid BFS/DFS
int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};
bool inside(int r, int c, int R, int C) { return r>=0 && r<R && c>=0 && c<C; }
// standard BFS but neighbors are (r+dr[k], c+dc[k])
Bipartite Check
vector<int> color(n, -1);
bool isBipartite = true;
for (int s = 0; s < n && isBipartite; s++) {
if (color[s] != -1) continue;
queue<int> q; [Link](s); color[s] = 0;
while (![Link]() && isBipartite) {
int u = [Link](); [Link]();
for (int v : adj[u]) {
if (color[v] == -1) { color[v] = color[u]1; [Link](v); }
else if (color[v] == color[u]) { isBipartite = false; break; }
}
}
}
Cycle Detection
// undirected (DSU is simplest, see Section 9) or DFS with parent tracking
// directed: DFS with 3 colors (white/gray/black) a back-edge to a GRAY node means a cycle
vector<int> state(n, 0); // 0=white,1=gray,2=black
bool hasCycle = false;
void dfs(int u) {
state[u] = 1;
for (int v : adj[u]) {
if (state[v] == 1) hasCycle = true;
else if (state[v] == 0) dfs(v);
}
state[u] = 2;
}
parent[b] = a;
if (rnk[a] == rnk[b]) rnk[a]++;
return true;
}
};
Kruskal's MST
struct Edge { int u, v; long long w; };
vector<Edge> edges; // fill with all edges
sort(all(edges), [](Edge&a, Edge&b){ return a.w < b.w; });
DSU dsu(n);
long long mstWeight = 0; int used = 0;
for (auto& e : edges) {
if ([Link](e.u, e.v)) { mstWeight += e.w; used++; }
}
// used == n-1 means MST connects everything
Prim's MST
vector<bool> inMST(n, false);
priority_queue<pii, vector<pii>, greater<pii>> pq; // {weight, node}
[Link]({0, 0});
long long mstWeight = 0;
while (![Link]()) {
auto [w, u] = [Link](); [Link]();
if (inMST[u]) continue;
inMST[u] = true; mstWeight += w;
for (auto [v, wt] : wadj[u]) if (!inMST[v]) [Link]({wt, v});
}
Dijkstra
vector<long long> dist(n, LLONG_MAX);
priority_queue<pii, vector<pii>, greater<pii>> pq; // {dist, node}
dist[src] = 0; [Link]({0, src});
while (![Link]()) {
auto [d, u] = [Link](); [Link]();
if (d > dist[u]) continue;
for (auto [v, w] : wadj[u]) {
if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; [Link]({dist[v], v}); }
}
}
0-1 BFS
vector<int> dist(n, INT_MAX);
deque<int> dq;
dist[src] = 0; dq.push_back(src);
while (![Link]()) {
int u = [Link](); dq.pop_front();
for (auto [v, w] : wadj[u]) { // w is 0 or 1
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
if (w == 0) dq.push_front(v); else dq.push_back(v);
}
}
}
ECPC Team Reference 19
Bellman-Ford
vector<long long> dist(n, LLONG_MAX);
dist[src] = 0;
for (int i = 0; i < n-1; i++)
for (auto& e : edges) // e = {u, v, w}
if (dist[e.u] != LLONG_MAX && dist[e.u] + e.w < dist[e.v])
dist[e.v] = dist[e.u] + e.w;
// one more pass: if any edge still relaxes, there's a negative cycle
8. Trees
Tree DFS + Subtree Sizes
vector<int> subSize(n, 1);
void dfs(int u, int parent) {
for (int v : adj[u]) {
if (v == parent) continue;
dfs(v, u);
subSize[u] += subSize[v];
}
}
Rerooting Basics
Idea: do one DFS to compute answers rooted at a xed root, then a second DFS that moves the root to each neighbor
by combining parent's rerooted answer with the current subtree answer (add/remove u's own contribution). Useful when
you need the answer for every node as root in O(n) total.
ECPC Team Reference 23
9. Data Structures
Fenwick Tree (Binary Indexed Tree) point update, prex sum
struct Fenwick {
vector<long long> bit;
int n;
Fenwick(int n) : n(n), bit(n+1, 0) {}
void update(int i, long long delta) { // 1-indexed
for (; i <= n; i += i & (-i)) bit[i] += delta;
}
long long query(int i) { // prefix sum [1, i]
long long s = 0;
for (; i > 0; i -= i & (-i)) s += bit[i];
return s;
}
long long rangeQuery(int l, int r) { return query(r) - query(l-1); }
};
Trie
struct Trie {
struct Node { int children[26] = {}; bool isEnd = false; };
vector<Node> nodes;
Trie() { nodes.push_back(Node()); }
void insert(const string& s) {
int cur = 0;
for (char c : s) {
int idx = c - 'a';
if (!nodes[cur].children[idx]) { nodes[cur].children[idx] = [Link](); nodes.push_back(Node()); }
cur = nodes[cur].children[idx];
}
ECPC Team Reference 25
nodes[cur].isEnd = true;
}
bool search(const string& s) {
int cur = 0;
for (char c : s) {
int idx = c - 'a';
if (!nodes[cur].children[idx]) return false;
cur = nodes[cur].children[idx];
}
return nodes[cur].isEnd;
}
};
ECPC Team Reference 26
0/1 Knapsack
vector<long long> dp(W+1, 0);
for (int i = 0; i < n; i++)
for (int w = W; w >= wt[i]; w--) // reverse to avoid reusing item i
dp[w] = max(dp[w], dp[w-wt[i]] + val[i]);
// unbounded knapsack: loop w forward instead of reverse
Bitmask DP (TSP-style)
vector<vector<long long>> dp(1<<n, vector<long long>(n, LLONG_MAX/2));
dp[1][0] = 0; // start at node 0, only node 0 visited
for (int mask = 1; mask < (1<<n); mask++)
for (int u = 0; u < n; u++) {
if (!(mask & (1<<u)) || dp[mask][u] == LLONG_MAX/2) continue;
for (int v = 0; v < n; v++) {
if (mask & (1<<v)) continue;
int nmask = mask | (1<<v);
dp[nmask][v] = min(dp[nmask][v], dp[mask][u] + cost[u][v]);
}
}
Tree DP
See Section 8 (Trees) max independent set example.
11. Strings
Basics
string s = "hello";
[Link](1, 3); // "ell" (start=1, length=3)
[Link]("ll"); // index or string::npos
reverse(all(s));
s += "world";
to_string(123); stoi("123"); stoll("123456789012");
Frequency count
vector<int> freq(26, 0);
for (char c : s) freq[c - 'a']++;
Palindrome check
bool isPalindrome(string s) {
int l = 0, r = [Link]()-1;
while (l < r) if (s[l++] != s[r--]) return false;
return true;
}
Z-function
vector<int> zFunction(const string& s) {
int n = [Link]();
vector<int> z(n, 0);
int l = 0, r = 0;
for (int i = 1; i < n; i++) {
if (i < r) z[i] = min(r-i, z[i-l]);
while (i+z[i] < n && s[z[i]] == s[i+z[i]]) z[i]++;
if (i+z[i] > r) { l = i; r = i+z[i]; }
}
return z;
}
// z[i] = length of longest common prefix of s and s[i:]
// pattern matching: run on pattern + '#' + text, look for z[i] == [Link]()
}
void buildFail() {
queue<int> q;
for (auto& [c, v] : trie[0].next) { trie[v].fail = 0; [Link](v); }
while (![Link]()) {
int u = [Link](); [Link]();
for (auto& [c, v] : trie[u].next) {
trie[v].fail = trie[trie[u].fail].[Link](c) ? trie[trie[u].fail].next[c] : 0;
[Link](v);
}
}
}
};
ECPC Team Reference 31
12. Greedy
Sorting-based Greedy
Sort by a key that makes the locally-best choice also globally optimal, then sweep once. Always sanity-check against samples
greedy is wrong more often than it looks right.
13. Geometry
Point / Vector
struct Point { double x, y; };
Point operator-(Point a, Point b) { return {a.x-b.x, a.y-b.y}; }
Point operator+(Point a, Point b) { return {a.x+b.x, a.y+b.y}; }
Orientation
int orientation(Point a, Point b, Point c) {
double val = cross({b.x-a.x, b.y-a.y}, {c.x-a.x, c.y-a.y});
if (val > 1e-9) return 1; // counter-clockwise
if (val < -1e-9) return -1; // clockwise
return 0; // collinear
}
Distance
double dist(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); }