0% found this document useful (0 votes)
405 views25 pages

Omogen Heap: KTH Royal Institute of Technology

KTH Royal Institute of Technology This document contains a summary of mathematics concepts and algorithms troubleshooting tips. It begins with contact information for three people and a date. It then provides mathematics formulas and explanations for equations, geometry, triangles, and trigonometric identities. The rest of the document offers advice for troubleshooting algorithms, including checking for infinite loops, complexity, memory usage, test cases, and edge cases.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
405 views25 pages

Omogen Heap: KTH Royal Institute of Technology

KTH Royal Institute of Technology This document contains a summary of mathematics concepts and algorithms troubleshooting tips. It begins with contact information for three people and a date. It then provides mathematics formulas and explanations for equations, geometry, triangles, and trigonometric identities. The rest of the document offers advice for troubleshooting algorithms, including checking for infinite loops, complexity, memory usage, test cases, and edge cases.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

KTH Royal Institute of Technology

Omogen Heap
Simon Lindholm, Johan Sannemo, Mårten Wiman

2019-04-17
KTH template .bashrc .vimrc troubleshoot 1
Contest (1) Any possible infinite recursion?
tan v + tan w
tan(v + w) =
Invalidated pointers or iterators? 1 − tan v tan w
template.cpp Are you using too much memory?
15 lines Debug with resubmits (e.g. remapped signals, see Various).
v+w v−w
sin v + sin w = 2 sin cos
#include <bits/stdc++.h> 2 2
using namespace std; Time limit exceeded:
Do you have any possible infinite loops?
v+w v−w
cos v + cos w = 2 cos cos
#define rep(i, a, b) for(int i = a; i < (b); ++i) What is the complexity of your algorithm? 2 2
#define trav(a, x) for(auto& a : x) Are you copying a lot of unnecessary data? (References)
#define all(x) x.begin(), x.end() How big is the input and output? (consider scanf) (V + W ) tan(v − w)/2 = (V − W ) tan(v + w)/2
#define sz(x) (int)(x).size() Avoid vector, map. (use arrays/unordered_map)
typedef long long ll; What do your team mates think about your algorithm? where V, W are lengths of sides opposite angles v, w.
typedef pair<int, int> pii;
typedef vector<int> vi; Memory limit exceeded: a cos x + b sin x = r cos(x − φ)
What is the max amount of memory your algorithm should need?
int main() { Are you clearing all datastructures between test cases? a sin x + b cos x = r sin(x + φ)
cin.sync_with_stdio(0); cin.tie(0);
cin.exceptions(cin.failbit); √
} Mathematics (2) where r = a2 + b2 , φ = atan2(b, a).

.bashrc 3 lines 2.1 Equations 2.4 Geometry


alias c=’g++ -Wall -Wconversion -Wfatal-errors -g -std=c++14 \ √
-fsanitize=undefined,address’ −b ± b2 − 4ac 2.4.1 Triangles
xmodmap -e ’clear lock’ -e ’keycode 66=less greater’ #caps = <> ax2 + bx + c = 0 ⇒ x =
2a Side lengths: a, b, c
.vimrc a+b+c
2 lines The extremum is given by x = −b/2a. Semiperimeter: p =
set cin aw ai is ts=4 sw=4 tm=50 nu noeb bg=dark ru cul p 2
sy on | im jk <esc> | im kj <esc> | no ; : Area: A = p(p − a)(p − b)(p − c)
ed − bf abc
troubleshoot.txt ax + by = e x= Circumradius: R =
52 lines ad − bc 4A

Pre-submit: cx + dy = f af − ec A
Write a few simple test cases, if sample is not enough. y= Inradius: r =
Are time limits close? If so, generate max cases. ad − bc p
Is the memory usage fine? Length of median (divides
√ triangle into two equal-area
Could anything overflow? In general, given an equation Ax = b, the solution to a
Make sure to submit the right file. triangles): ma = 12 2b2 + 2c2 − a2
variable xi is given by Length
Wrong answer: v of "bisector (divides angles in two):
det A0i 2 #
Print your solution! Print debug output, as well.
u 
xi =
u a
Are you clearing all datastructures between test cases?
det A sa = tbc 1 −
Can your algorithm handle the whole range of input? b+c
Read the full problem statement again.
Do you handle all corner cases correctly? where A0i is A with the i’th column replaced by b. sin α sin β sin γ 1
Have you understood the problem correctly? Law of sines: = = =
Any uninitialized variables?
2.2 Recurrences a b c 2R
Any overflows? Law of cosines: a2 = b2 + c2 − 2bc cos α
Confusing N and M, i and j, etc.? α+β
Are you sure your algorithm works? If an = c1 an−1 + · · · + ck an−k , and r1 , . . . , rk are distinct a+b tan
What special cases have you not thought of? roots of xk + c1 xk−1 + · · · + ck , there are d1 , . . . , dk s.t. Law of tangents: = 2
Are you sure the STL functions you use work as you think? a−b α−β
Add some assertions, maybe resubmit. tan
Create some testcases to run your algorithm on. an = d1 r1n + · · · + dk rkn . 2
Go through the algorithm for a simple case.
Go through this list again. Non-distinct roots r become polynomial factors, e.g. 2.4.2 Quadrilaterals
Explain your algorithm to a team mate.
Ask the team mate to look at your code. an = (d1 n + d2 )rn .
Go for a small walk, e.g. to the toilet.
With side lengths a, b, c, d, diagonals e, f , diagonals angle θ,
Is your output format correct? (including whitespace) 2.3 Trigonometry area A and magic flux F = b2 + d2 − a2 − c2 :
Rewrite your solution from the start or let a team mate do it.

Runtime error: p
Have you tested all corner cases locally? sin(v + w) = sin v cos w + cos v sin w 4A = 2ef · sin θ = F tan θ = 4e2 f 2 − F 2
Any uninitialized variables?
cos(v + w) = cos v cos w − sin v sin w
Are you reading or writing outside the range of any vector?
Any assertions that might fail?
For cyclic quadrilateralspthe sum of opposite angles is 180◦ ,
Any possible division by 0? (mod 0 for example) ef = ac + bd, and A = (p − a)(p − b)(p − c)(p − d).
KTH 2
2.4.3 Spherical coordinates 2.7 Series First success distribution
z
x2 x3
r ex = 1 + x + + + . . . , (−∞ < x < ∞) The number of trials needed to get the first success in
2! 3!
y independent yes/no experiments, each wich yields success
x2 x3 x4 with probability p is Fs(p), 0 ≤ p ≤ 1.
ln(1 + x) = x − + − + . . . , (−1 < x ≤ 1)
x 2 3 4
p(k) = p(1 − p)k−1 , k = 1, 2, . . .
√ x x 2
2x 5x 3 4
1+x=1+ − + − + . . . , (−1 ≤ x ≤ 1)
2 8 32 128 1 2 1−p
x = r sin θ cos φ
p
r = xp 2 + y2 + z2 µ= ,σ =
x3
x 5
x 7 p p2
y = r sin θ sin φ θ = acos(z/ x2 + y 2 + z 2 ) sin x = x − + − + . . . , (−∞ < x < ∞)
3! 5! 7!
z = r cos θ φ = atan2(y, x) Poisson distribution
x2 x4 x6
cos x = 1 − + − + . . . , (−∞ < x < ∞)
2.5 Derivatives/Integrals 2! 4! 6! The number of events occurring in a fixed period of time t if
these events occur with a known average rate κ and
2.8 Probability theory independently of the time since the last event is
d 1 d 1 Po(λ), λ = tκ.
arcsin x = √ arccos x = − √ Let X be a discrete random variable with probability pX (x)
dx 1 − x2 dx 1 − x2
of assuming the valuePx. It will then have an expected value
d d 1 λk
tan x = 1 + tan2 x arctan x = (mean) µ = E(X) = x xpX (x) and P variance p(k) = e−λ , k = 0, 1, 2, . . .
dx dx 1 + x2 σ 2 = V (X) = E(X 2 ) − (E(X))2 = x (x − E(X))2 pX (x) k!
ln | cos ax| sin ax − ax cos ax
Z Z
tan ax = − x sin ax = where σ is the standard deviation. If X is instead
a a2 continuous it will have a probability density function fX (x) µ = λ, σ 2 = λ
Z √ Z ax
2 π e and the sums above will instead be integrals with pX (x)
e−x = erf(x) xeax dx = 2 (ax − 1)
2 a replaced by fX (x). 2.8.2 Continuous distributions
Expectation is linear: Uniform distribution
Integration by parts:
E(aX + bY ) = aE(X) + bE(Y ) If the probability density function is constant between a and
Z b Z b
f (x)g(x)dx = [F (x)g(x)]ba − 0
F (x)g (x)dx b and 0 elsewhere it is U(a, b), a < b.
For independent X and Y ,
a a
1

2 2 b−a a<x<b
V (aX + bY ) = a V (X) + b V (Y ). f (x) =
2.6 Sums 0 otherwise

cb+1 − ca 2.8.1 Discrete distributions a+b 2 (b − a)2


ca + ca+1 + · · · + cb = , c 6= 1 µ= ,σ =
c−1 Binomial distribution 2 12

n(n + 1) The number of successes in n independent yes/no Exponential distribution


1 + 2 + 3 + ··· + n = experiments, each which yields success with probability p is
2
n(2n + 1)(n + 1) Bin(n, p), n = 1, 2, . . . , 0 ≤ p ≤ 1. The time between events in a Poisson process is
2 2 2 2
1 + 2 + 3 + ··· + n = Exp(λ), λ > 0.
6  
n k
n2 (n + 1)2 p(k) = p (1 − p)n−k λe−λx
3 3 3 3

1 + 2 + 3 + ··· + n = k x≥0
4 f (x) =
0 x<0
n(n + 1)(2n + 1)(3n2 + 3n − 1)
14 + 24 + 34 + · · · + n4 = µ = np, σ 2 = np(1 − p)
30 1 2 1
Bin(n, p) is approximately Po(np) for small p. µ= ,σ = 2
λ λ
KTH OrderStatisticTree HashMap SegmentTree LazySegmentTree UnionFind SubMatrix 3
Normal distribution OrderStatisticTree.h if (lo + 1 < hi) {
Description: A set (not multiset!) with support for finding the n’th ele- int mid = lo + (hi - lo)/2;
ment, and finding the index of an element. To get a map, change null type. l = new Node(v, lo, mid); r = new Node(v, mid, hi);
Most real random values with mean µ and variance σ 2 are Time: O (log N ) 16 lines
val = max(l->val, r->val);
}
well described by N (µ, σ 2 ), σ > 0. #include <bits/extc++.h> else val = v[lo];
using namespace __gnu_pbds; }
1 −
(x−µ)2
template<class T>
int query(int L, int R) {
f (x) = √ e 2σ 2
using Tree = tree<T, null_type, less<T>, rb_tree_tag,
if (R <= lo || hi <= L) return -inf;
2πσ 2 tree_order_statistics_node_update>;
if (L <= lo && hi <= R) return val;
push();
return max(l->query(L, R), r->query(L, R));
If X1 ∼ N (µ1 , σ12 ) and X2 ∼ N (µ2 , σ22 ) then void example() { }
Tree<int> t, t2; t.insert(8); void set(int L, int R, int x) {
auto it = t.insert(10).first; if (R <= lo || hi <= L) return;
aX1 + bX2 + c ∼ N (µ1 + µ2 + c, a2 σ12 + b2 σ22 ) assert(it == t.lower_bound(9)); if (L <= lo && hi <= R) mset = val = x, madd = 0;
assert(t.order_of_key(10) == 1); else {
assert(t.order_of_key(11) == 2); push(), l->set(L, R, x), r->set(L, R, x);
assert(*t.find_by_order(0) == 8); val = max(l->val, r->val);
2.9 Markov chains }
t.join(t2); // assuming T < T2 or T > T2, merge t2 into t }
}
void add(int L, int R, int x) {
A Markov chain is a discrete random process with the if (R <= lo || hi <= L) return;
HashMap.h
property that the next state depends only on the current Description: Hash map with the same API as unordered map, but ∼3x
if (L <= lo && hi <= R) {
if (mset != inf) mset += x;
state. Let X1 , X2 , . . . be a sequence of random variables faster. Initial capacity must be a power of 2 (if provided). 2 lines else madd += x;
generated by the Markov process. Then there is a transition #include <bits/extc++.h> val += x;
__gnu_pbds::gp_hash_table<ll, int> h({},{},{},{}, {1 << 16}); }
matrix P = (pij ), with pij = Pr(Xn = i|Xn−1 = j), and else {
p(n) = Pn p(0) is the probability distribution for Xn (i.e., push(), l->add(L, R, x), r->add(L, R, x);
(n) SegmentTree.h val = max(l->val, r->val);
pi = Pr(Xn = i)), where p(0) is the initial Description: Zero-indexed max-tree. Bounds are inclusive to the left and }
exclusive to the right. Can be changed by modifying T, LOW and f. }
distribution. Time: O (log N ) 19 lines void push() {
struct Tree { if (!l) {
π is a stationary distribution if π = πP. If the Markov chain int mid = lo + (hi - lo)/2;
typedef int T;
is irreducible (it is possible to get to any state from any static const T LOW = INT_MIN; l = new Node(lo, mid); r = new Node(mid, hi);
1 T f(T a, T b) { return max(a, b); } // (any associative fn ) }
state), then πi = E(T i)
where E(Ti ) is the expected time if (mset != inf)
vector<T> s; int n;
l->set(lo,hi,mset), r->set(lo,hi,mset), mset = inf;
between two visits in state i. πj /πi is the expected number Tree(int n = 0, T def = 0) : s(2*n, def), n(n) {}
else if (madd)
void update(int pos, T val) {
of visits in state j between two visits in state i. for (s[pos += n] = val; pos > 1; pos /= 2) l->add(lo,hi,madd), r->add(lo,hi,madd), madd = 0;
s[pos / 2] = f(s[pos & ∼1], s[pos | 1]); }
For a connected, undirected and non-bipartite graph, where } };
T query(int b, int e) { // query [ b , e)
the transition probability is uniform among all neighbors, πi T ra = LOW, rb = LOW;
is proportional to node i’s degree. for (b += n, e += n; b < e; b /= 2, e /= 2) {
UnionFind.h
Description: Disjoint-set data structure.
if (b % 2) ra = f(ra, s[b++]);
Time: O (α(N )) 13 lines
if (e % 2) rb = f(s[--e], rb);
A Markov chain is ergodic if the asymptotic distribution is } struct UF {
independent of the initial distribution. A finite Markov return f(ra, rb); vi e;
} UF(int n) : e(n, -1) {}
chain is ergodic iff it is irreducible and aperiodic (i.e., the }; bool same_set(int a, int b) { return find(a) == find(b); }
gcd of cycle lengths is 1). limk→∞ Pk = 1π. int size(int x) { return -e[find(x)]; }
int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
A Markov chain is an A-chain if the states can be LazySegmentTree.h void join(int a, int b) {
Description: Segment tree with ability to add or set values of large intervals, a = find(a), b = find(b);
partitioned into two sets A and G, such that all states in A and compute max of intervals. Can be changed to other things. Use with a if (a == b) return;
bump allocator for better performance, and SmallPtr or implicit indices to
are absorbing (pii = 1), and all states in G leads to an save memory.
if (e[a] > e[b]) swap(a, b);
e[a] += e[b]; e[b] = a;
absorbing state in A. The probability for absorption in state Usage: Node* tr = new Node(v, 0, sz(v)); }
O (log N ).
i ∈ A, when the initial state is j, is aij = pij + k∈G aik pkj . Time:
P
};
"../various/BumpAllocator.h" 50 lines
The expectedP time until absorption, when the initial state is const int inf = 1e9;
i, is ti = 1 + k∈G pki tk . struct Node { SubMatrix.h
Node *l = 0, *r = 0; Description: Calculate submatrix sums quickly, given upper-left and lower-
int lo, hi, mset = inf, madd = 0, val = -inf; right corners (half-open).
Data structures (3) Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of −in f
Node(vi& v, int lo, int hi) : lo(lo), hi(hi) {
Usage: SubMatrix<int> m(matrix);
m.sum(0, 0, 2, 2); // top left 4 elements
KTH Matrix LineContainer Treap FenwickTree FenwickTree2d 4
Time: O N 2 + Q

13 lines
else x->p = div(y->m - x->m, x->k - y->k);
return x->p >= y->p; // Example application : move the range [ l , r ) to index k
template<class T> } void move(Node*& t, int l, int r, int k) {
struct SubMatrix { void add(ll k, ll m) { Node *a, *b, *c;
vector<vector<T>> p; auto z = insert({k, m, 0}), y = z++, x = y; tie(a,b) = split(t, l); tie(b,c) = split(b, r - l);
SubMatrix(vector<vector<T>>& v) { while (isect(y, z)) z = erase(z); if (k <= l) t = merge(ins(a, b, k), c);
int R = sz(v), C = sz(v[0]); if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); else t = merge(a, ins(c, b, k - r));
p.assign(R+1, vector<T>(C+1)); while ((y = x) != begin() && (--x)->p >= y->p) }
rep(r,0,R) rep(c,0,C) isect(x, erase(y));
p[r+1][c+1] = v[r][c] + p[r][c+1] + p[r+1][c] - p[r][c]; }
} ll query(ll x) {
T sum(int u, int l, int d, int r) { assert(!empty());
FenwickTree.h
return p[d][r] - p[d][l] - p[u][r] + p[u][l]; Description: Computes partial sums a[0] + a[1] + ... + a[pos - 1], and
auto l = *lower_bound(x);
} updates single elements a[i], taking the difference between the old and new
return l.k * x + l.m;
}; value.
}
Time: Both operations are O (log N ).
}; 22 lines

Matrix.h struct FT {
Description: Basic operations on square matrices. vector<ll> s;
Usage: Matrix<int, 3> A;
Treap.h FT(int n) : s(n) {}
Description: A short self-balancing tree. It acts as a sequential container void update(int pos, ll dif) { // a [ pos ] += d i f
A.d = {{{{1,2,3}}, {{4,5,6}}, {{7,8,9}}}}; with log-time splits/joins, and is easy to augment with additional data.
vector<int> vec = {1,2,3}; for (; pos < sz(s); pos |= pos + 1) s[pos] += dif;
Time: O (log N ) 55 lines }
vec = (AˆN) * vec; 26 lines
struct Node { ll query(int pos) { // sum of values in [0 , pos)
template<class T, int N> struct Matrix { Node *l = 0, *r = 0; ll res = 0;
typedef Matrix M; int val, y, c = 1; for (; pos > 0; pos &= pos - 1) res += s[pos-1];
array<array<T, N>, N> d{}; Node(int val) : val(val), y(rand()) {} return res;
M operator*(const M& m) const { void recalc(); }
M a; }; int lower_bound(ll sum) {// min pos s t sum of [0 , pos ] >= sum
rep(i,0,N) rep(j,0,N) // Returns n i f no sum i s >= sum, or −1 i f empty sum i s .
rep(k,0,N) a.d[i][j] += d[i][k]*m.d[k][j]; int cnt(Node* n) { return n ? n->c : 0; } if (sum <= 0) return -1;
return a; void Node::recalc() { c = cnt(l) + cnt(r) + 1; } int pos = 0;
} for (int pw = 1 << 25; pw; pw >>= 1) {
vector<T> operator*(const vector<T>& vec) const { template<class F> void each(Node* n, F f) { if (pos + pw <= sz(s) && s[pos + pw-1] < sum)
vector<T> ret(N); if (n) { each(n->l, f); f(n->val); each(n->r, f); } pos += pw, sum -= s[pos-1];
rep(i,0,N) rep(j,0,N) ret[i] += d[i][j] * vec[j]; } }
return ret; return pos;
} pair<Node*, Node*> split(Node* n, int k) { }
M operatorˆ(ll p) const { if (!n) return {}; };
assert(p >= 0); if (cnt(n->l) >= k) { // ”n−>val >= v” for lower bound(v)
M a, b(*this); auto pa = split(n->l, k);
rep(i,0,N) a.d[i][i] = 1;
while (p) {
n->l = pa.second; FenwickTree2d.h
n->recalc(); Description: Computes sums a[i,j] for all i<I, j<J, and increases single ele-
if (p&1) a = a*b; return {pa.first, n};
b = b*b; ments a[i,j]. Requires that the elements to be updated are known in advance
} else { (call fakeUpdate() before init()).
p >>= 1;
}
auto pa = split(n->r, k - cnt(n->l) - 1); Time: O log2 N . (Use persistent segment trees for O (log N ).)
n->r = pa.first; "FenwickTree.h" 22 lines
return a; n->recalc();
} struct FT2 {
return {n, pa.second};
}; vector<vi> ys; vector<FT> ft;
}
FT2(int limx) : ys(limx) {}
}
void fakeUpdate(int x, int y) {
LineContainer.h Node* merge(Node* l, Node* r) {
for (; x < sz(ys); x |= x + 1) ys[x].push_back(y);
Description: Container where you can add lines of the form kx+m, and }
query maximum values at points x. Useful for dynamic programming. if (!l) return r;
void init() {
Time: O (log N ) if (!r) return l;
30 lines trav(v, ys) sort(all(v)), ft.emplace_back(sz(v));
if (l->y > r->y) {
}
struct Line { l->r = merge(l->r, r);
int ind(int x, int y) {
mutable ll k, m, p; l->recalc();
return (int)(lower_bound(all(ys[x]), y) - ys[x].begin()); }
bool operator<(const Line& o) const { return k < o.k; } return l;
void update(int x, int y, ll dif) {
bool operator<(ll x) const { return p < x; } } else {
for (; x < sz(ys); x |= x + 1)
}; r->l = merge(l, r->l);
ft[x].update(ind(x, y), dif);
r->recalc();
}
struct LineContainer : multiset<Line, less<>> { return r;
ll query(int x, int y) {
// ( for doubles , use i nf = 1/.0 , div (a , b) = a/b) }
ll sum = 0;
const ll inf = LLONG_MAX; }
for (; x; x &= x - 1)
ll div(ll a, ll b) { // floored division
sum += ft[x-1].query(ind(x-1, y));
return a / b - ((a ˆ b) < 0 && a % b); } Node* ins(Node* t, Node* n, int pos) {
return sum;
bool isect(iterator x, iterator y) { auto pa = split(t, pos);
}
if (y == end()) { x->p = inf; return false; } return merge(merge(pa.first, n), pa.second);
};
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; }
KTH RMQ GoldenSectionSearch Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence HillClimbing 5
RMQ.h double b = a.back(), c; a.back() = 0; ll b = 1;
Description: Range Minimum Queries on an array. Returns min(V[a], V[a for(int i=sz(a)-1; i--;) c = a[i], a[i] = a[i+1]*x0+b, b=c; rep(i,0,n) { ++m;
+ 1], ... V[b - 1]) in constant time. a.pop_back(); ll d = s[i] % mod;
Usage: RMQ rmq(values); } rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
rmq.query(inclusive, exclusive); }; if (!d) continue;
Time: O (|V | log |V | + Q) 19 lines
T = C; ll coef = d * modpow(b, mod-2) % mod;
rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
template<class T> PolyRoots.h if (2 * L > i) continue;
struct RMQ { Description: Finds the real roots to a polynomial. L = i + 1 - L; B = T; b = d; m = 0;
vector<vector<T>> jmp; Usage: poly roots({{2,-3,1}},-1e9,1e9) // solve xˆ2-3x+2 = 0 }
Time: O n2 log(1/)

RMQ(const vector<T>& V) { "Polynomial.h" 23 lines C.resize(L + 1); C.erase(C.begin());
int N = sz(V), on = 1, depth = 1; vector<double> poly_roots(Poly p, double xmin, double xmax) { trav(x, C) x = (mod - x) % mod;
while (on < sz(V)) on *= 2, depth++; if (sz(p.a) == 2) { return {-p.a[0]/p.a[1]}; } return C;
jmp.assign(depth, V); vector<double> ret; }
rep(i,0,depth-1) rep(j,0,N) Poly der = p;
jmp[i+1][j] = min(jmp[i][j], der.diff();
jmp[i][min(N - 1, j + (1 << i))]); auto dr = poly_roots(der, xmin, xmax);
LinearRecurrence.h
} Description: Generates the k’th term of an n-order linear recurrence
dr.push_back(xmin-1); P
dr.push_back(xmax+1);
S[i] = j S[i − j − 1]tr[j], given S[0 . . . n − 1] and tr[0 . . . n − 1]. Faster than
T query(int a, int b) { sort(all(dr)); matrix multiplication. Useful together with Berlekamp–Massey.
assert(a < b); // or return i n f i f a == b rep(i,0,sz(dr)-1) { Usage: linearRec({0, 1}, {1, 1}, k) // k’th Fibonacci number
Time: O n2 log k

int dep = 31 - __builtin_clz(b - a); double l = dr[i], h = dr[i+1]; 26 lines
return min(jmp[dep][a], jmp[dep][b - (1 << dep)]); bool sign = p(l) > 0;
} typedef vector<ll> Poly;
if (sign ˆ (p(h) > 0)) { ll linearRec(Poly S, Poly tr, ll k) {
}; rep(it,0,60) { // while (h − l > 1e−8) int n = sz(S);
double m = (l + h) / 2, f = p(m);
if ((f <= 0) ˆ sign) l = m; auto combine = [&](Poly a, Poly b) {
Numerical (4) else h = m; Poly res(n * 2 + 1);
} rep(i,0,n+1) rep(j,0,n+1)
ret.push_back((l + h) / 2);
GoldenSectionSearch.h }
res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
Description: Finds the argument minimizing the function f in the inter- for (int i = 2 * n; i > n; --i) rep(j,0,n)
} res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
val [a, b] assuming f is unimodal on the interval, i.e. has only one local
return ret; res.resize(n + 1);
minimum. The maximum error in the result is eps. Works equally well for
} return res;
maximization with a small change in the code. See TernarySearch.h in the
Various chapter for a discrete version. };
Usage: double func(double x) { return 4+x+.3*x*x; } PolyInterpolate.h Poly pol(n + 1), e(pol);
double xmin = gss(-1000,1000,func); Description: Given n points (x[i], y[i]), computes an n-1-degree polynomial
Time: O (log((b − a)/)) pol[0] = e[1] = 1;
14 lines p that passes through them: p(x) = a[0] ∗ x0 + ... + a[n − 1] ∗ xn−1 . For
double gss(double a, double b, double (*f)(double)) { numerical precision, pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1.
for (++k; k; k /= 2) {
Time: O n2

double r = (sqrt(5)-1)/2, eps = 1e-7; 13 lines if (k % 2) pol = combine(pol, e);
double x1 = b - r*(b-a), x2 = a + r*(b-a); typedef vector<double> vd; e = combine(e, e);
double f1 = f(x1), f2 = f(x2); vd interpolate(vd x, vd y, int n) { }
while (b-a > eps) vd res(n), temp(n);
if (f1 < f2) { //change to > to find maximum rep(k,0,n-1) rep(i,k+1,n) ll res = 0;
b = x2; x2 = x1; f2 = f1; y[i] = (y[i] - y[k]) / (x[i] - x[k]); rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod;
x1 = b - r*(b-a); f1 = f(x1); double last = 0; temp[0] = 1; return res;
} else { rep(k,0,n) rep(i,0,n) { }
a = x1; x1 = x2; f1 = f2; res[i] += y[k] * temp[i];
x2 = a + r*(b-a); f2 = f(x2); swap(last, temp[i]);
} HillClimbing.h
temp[i] -= last * x[k]; Description: Poor man’s optimization for unimodal functions.
return a; } 16 lines
} return res; typedef array<double, 2> P;
}
Polynomial.h double func(P p);
17 lines

struct Poly { BerlekampMassey.h pair<double, P> hillClimb(P start) {


vector<double> a; Description: Recovers any n-order linear recurrence relation from the first pair<double, P> cur(func(start), start);
double operator()(double x) const { 2n terms of the recurrence. Useful for guessing linear recurrences after brute- for (double jmp = 1e9; jmp > 1e-20; jmp /= 2) {
double val = 0; forcing the first terms. Should work on any field, but numerical stability for rep(j,0,100) rep(dx,-1,2) rep(dy,-1,2) {
for(int i = sz(a); i--;) (val *= x) += a[i]; floats is not guaranteed. Output will have size ≤ n. P p = cur.second;
return val; Usage: BerlekampMassey({0, 1, 1, 3, 5, 11}) // {1, 2} p[0] += dx*jmp;
} "../number-theory/ModPow.h" 20 lines p[1] += dy*jmp;
void diff() { vector<ll> BerlekampMassey(vector<ll> s) { cur = min(cur, make_pair(func(p), p));
rep(i,1,sz(a)) a[i-1] = i*a[i]; int n = sz(s), L = 0, m = 0; }
a.pop_back(); vector<ll> C(n), B(n), T; }
} C[0] = B[0] = 1; return cur;
void divroot(double x0) { }
KTH Integrate IntegrateAdaptive Determinant IntDeterminant Simplex SolveLinear 6
Integrate.h rep(j,i+1,n) { rep(i,0,m) {
Description: Simple integration of a function over an interval using Simp- while (a[j][i] != 0) { // gcd step if (D[i][s] <= eps) continue;
son’s rule. The error should be proportional to h4 , although in practice you ll t = a[i][i] / a[j][i]; if (r == -1 || MP(D[i][n+1] / D[i][s], B[i])
will want to verify that the result is stable to desired precision when epsilon if (t) rep(k,i,n) < MP(D[r][n+1] / D[r][s], B[r])) r = i;
changes. 8 lines
a[i][k] = (a[i][k] - a[j][k] * t) % mod; }
swap(a[i], a[j]); if (r == -1) return false;
double quad(double (*f)(double), double a, double b) { ans *= -1; pivot(r, s);
const int n = 1000; } }
double h = (b - a) / 2 / n; } }
double v = f(a) + f(b); ans = ans * a[i][i] % mod;
rep(i,1,n*2) if (!ans) return 0; T solve(vd &x) {
v += f(a + i*h) * (i&1 ? 4 : 2); } int r = 0;
return v * h / 3; return (ans + mod) % mod; rep(i,1,m) if (D[i][n+1] < D[r][n+1]) r = i;
} } if (D[r][n+1] < -eps) {
pivot(r, n);
IntegrateAdaptive.h Simplex.h
if (!simplex(2) || D[m+1][n+1] < -eps) return -inf;
Description: Fast integration using an adaptive Simpson’s rule. rep(i,0,m) if (B[i] == -1) {
Description: Solves a general linear maximization problem: maximize cT x int s = 0;
Usage: double z, y;
subject to Ax ≤ b, x ≥ 0. Returns -inf if there is no solution, inf if there rep(j,1,n+1) ltj(D[i]);
double h(double x) { return x*x + y*y + z*z <= 1; }
are arbitrarily good solutions, or the maximum value of cT x otherwise. The pivot(i, s);
double g(double y) { ::y = y; return quad(h, -1, 1); }
input vector is set to an optimal x (or in the unbounded case, an arbitrary }
double f(double z) { ::z = z; return quad(g, -1, 1); }
solution fulfilling the constraints). Numerical stability is not guaranteed. For }
double sphereVol = quad(f, -1, 1), pi = sphereVol*3/4; 16 lines better performance, define variables such that x = 0 is viable. bool ok = simplex(1); x = vd(n);
typedef double d; Usage: vvd A = {{1,-1}, {-1,1}, {-1,-2}}; rep(i,0,m) if (B[i] < n) x[B[i]] = D[i][n+1];
d simpson(d (*f)(d), d a, d b) { vd b = {1,1,-4}, c = {-1,-1}, x; return ok ? D[m][n+1] : inf;
d c = (a+b) / 2; T val = LPSolver(A, b, c).solve(x); }
return (f(a) + 4*f(c) + f(b)) * (b-a) / 6; Time: O (N M ∗ #pivots), where a pivot may be e.g. an edge relaxation. };
} O (2n ) in the general case. 68 lines
d rec(d (*f)(d), d a, d b, d eps, d S) {
typedef double T; // long double , Rational , double + mod<P>... SolveLinear.h
d c = (a+b) / 2;
typedef vector<T> vd; Description: Solves A ∗ x = b. If there are multiple solutions, an arbitrary
d S1 = simpson(f, a, c);
typedef vector<vd> vvd; one is returned. Returns rank, or -1 if no solutions. Data in A and b is lost.
d S2 = simpson(f, c, b), T = S1 + S2;
if (abs (T - S) <= 15*eps || b-a < 1e-10) Time: O n2 m 38 lines
const T eps = 1e-8, inf = 1/.0;
return T + (T - S) / 15;
#define MP make_pair typedef vector<double> vd;
return rec(f, a, c, eps/2, S1) + rec(f, c, b, eps/2, S2);
#define ltj(X) if(s == -1 || MP(X[j],N[j]) < MP(X[s],N[s])) s=j const double eps = 1e-12;
}
d quad(d (*f)(d), d a, d b, d eps = 1e-8) {
struct LPSolver { int solveLinear(vector<vd>& A, vd& b, vd& x) {
return rec(f, a, b, eps, simpson(f, a, b));
int m, n; int n = sz(A), m = sz(x), rank = 0, br, bc;
}
vi N, B; if (n) assert(sz(A[0]) == m);
vvd D; vi col(m); iota(all(col), 0);
Determinant.h
Description: Calculates determinant of a matrix. Destroys the matrix. LPSolver(const vvd& A, const vd& b, const vd& c) : rep(i,0,n) {
Time: O N 3 15 lines
m(sz(b)), n(sz(c)), N(n+1), B(m), D(m+2, vd(n+2)) { double v, bv = 0;
rep(i,0,m) rep(j,0,n) D[i][j] = A[i][j]; rep(r,i,n) rep(c,i,m)
double det(vector<vector<double>>& a) { rep(i,0,m) { B[i] = n+i; D[i][n] = -1; D[i][n+1] = b[i];} if ((v = fabs(A[r][c])) > bv)
int n = sz(a); double res = 1; rep(j,0,n) { N[j] = j; D[m][j] = -c[j]; } br = r, bc = c, bv = v;
rep(i,0,n) { N[n] = -1; D[m+1][n] = 1; if (bv <= eps) {
int b = i; } rep(j,i,n) if (fabs(b[j]) > eps) return -1;
rep(j,i+1,n) if (fabs(a[j][i]) > fabs(a[b][i])) b = j; break;
if (i != b) swap(a[i], a[b]), res *= -1; void pivot(int r, int s) { }
res *= a[i][i]; T *a = D[r].data(), inv = 1 / a[s]; swap(A[i], A[br]);
if (res == 0) return 0; rep(i,0,m+2) if (i != r && abs(D[i][s]) > eps) { swap(b[i], b[br]);
rep(j,i+1,n) { T *b = D[i].data(), inv2 = b[s] * inv; swap(col[i], col[bc]);
double v = a[j][i] / a[i][i]; rep(j,0,n+2) b[j] -= a[j] * inv2; rep(j,0,n) swap(A[j][i], A[j][bc]);
if (v != 0) rep(k,i+1,n) a[j][k] -= v * a[i][k]; b[s] = a[s] * inv2; bv = 1/A[i][i];
} } rep(j,i+1,n) {
} rep(j,0,n+2) if (j != s) D[r][j] *= inv; double fac = A[j][i] * bv;
return res; rep(i,0,m+2) if (i != r) D[i][s] *= -inv; b[j] -= fac * b[i];
} D[r][s] = inv; rep(k,i+1,m) A[j][k] -= fac*A[i][k];
swap(B[r], N[s]); }
IntDeterminant.h } rank++;
Description: Calculates determinant using modular arithmetics. Modulos }
can also be removed to get a pure-integer version. bool simplex(int phase) {
Time: O N 3
 int x = m + phase - 1; x.assign(m, 0);
18 lines for (;;) { for (int i = rank; i--;) {
const ll mod = 12345; int s = -1; b[i] /= A[i][i];
ll det(vector<vector<ll>>& a) { rep(j,0,n+1) if (N[j] != -phase) ltj(D[x]); x[col[i]] = b[i];
int n = sz(a); ll ans = 1; if (D[x][s] >= -eps) return true; rep(j,0,i) b[j] -= A[j][i] * b[i];
rep(i,0,n) { int r = -1; }
KTH SolveLinear2 SolveLinearBinary MatrixInverse Tridiagonal FastFourierTransform NumberTheoreticTransform 7
return rank; // ( multiple solutions i f rank < m) int r = i, c = i; b[i+1] -= b[i]*sub[i]/diag[i];
} rep(j,i,n) rep(k,i,n) }
if (fabs(A[j][k]) > fabs(A[r][c])) }
r = j, c = k; for (int i = n; i--;) {
SolveLinear2.h if (fabs(A[r][c]) < 1e-12) return i; if (tr[i]) {
Description: To get all uniquely determined values of x back from Solve- A[i].swap(A[r]); tmp[i].swap(tmp[r]); swap(b[i], b[i-1]);
Linear, make the following changes: rep(j,0,n) diag[i-1] = diag[i];
"SolveLinear.h" 7 lines
swap(A[j][i], A[j][c]), swap(tmp[j][i], tmp[j][c]); b[i] /= super[i-1];
rep(j,0,n) if (j != i) // instead of rep( j , i +1,n) swap(col[i], col[c]); } else {
// . . . then at the end : double v = A[i][i]; b[i] /= diag[i];
x.assign(m, undefined); rep(j,i+1,n) { if (i) b[i-1] -= b[i]*super[i-1];
rep(i,0,rank) { double f = A[j][i] / v; }
rep(j,rank,m) if (fabs(A[i][j]) > eps) goto fail; A[j][i] = 0; }
x[col[i]] = b[i] / A[i][i]; rep(k,i+1,n) A[j][k] -= f*A[i][k]; return b;
fail:; } rep(k,0,n) tmp[j][k] -= f*tmp[i][k]; }
}
rep(j,i+1,n) A[i][j] /= v;
SolveLinearBinary.h
Description: Solves Ax = b over F2 . If there are multiple solutions, one is
rep(j,0,n) tmp[i][j] /= v;
A[i][i] = 1;
4.1 Fourier transforms
returned arbitrarily. Returns rank, or -1 if no solutions. Destroys A and b.
}
Time: O n2 m

34 lines FastFourierTransform.h
Description: fft(a, ...) computes fˆ(k) =
P
typedef bitset<1000> bs; for (int i = n-1; i > 0; --i) rep(j,0,i) { P· kx/N ) for all k.
x a[x] exp(2πi
double v = A[j][i]; Useful for convolution: conv(a, b) = c, where c[x] = a[i]b[x − i]. For
int solveLinear(vector<bs>& A, vi& b, bs& x, int m) { rep(k,0,n) tmp[j][k] -= v*tmp[i][k]; convolution of complex numbers or more than two vectors: FFT, multiply
int n = sz(A), rank = 0, br; } pointwise, divide by n, reverse(start+1, end), FFT back. For integers, con-
assert(m <= sz(x)); sider using a number-theoretic transform instead, to avoid rounding issues.
vi col(m); iota(all(col), 0); rep(i,0,n) rep(j,0,n) A[col[i]][col[j]] = tmp[i][j]; Time: O (N log N ), where N = |A| + |B| − 1 (∼1s for N = 222 ) 32 lines
rep(i,0,n) { return n;
} typedef complex<double> C;
for (br=i; br<n; ++br) if (A[br].any()) break;
typedef vector<double> vd;
if (br == n) {
rep(j,i,n) if(b[j]) return -1;
break;
Tridiagonal.h void fft(vector<C> &a, vector<C> &rt, vi& rev, int n) {
Description: x = tridiagonal(d, p, q, b) solves the equation system rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]);
}
for (int k = 1; k < n; k *= 2)
int bc = (int)A[br]._Find_next(i-1); 
b0
 
d0 p0 0 0 ··· 0

x0
 for (int i = 0; i < n; i += 2 * k) rep(j,0,k) {
swap(A[i], A[br]);
b1  q0 d1 p1 0 ··· 0 x1 C z = rt[j+k] * a[i+j+k]; // (25% faster i f hand−r o l l e d )
swap(b[i], b[br]);    
 b2   0 q1 d2 p2 ··· 0  x2  a[i + j + k] = a[i + j] - z;
swap(col[i], col[bc]);     
 b3 = .
 
. .
 x3 .
 a[i + j] += z;
rep(j,0,n) if (A[j][i] != A[j][bc]) { 
 . . .. .. .. .

. . . . }
 . . . .
   
A[j].flip(i); A[j].flip(bc); 
.
 
.

.  0 0 ··· qn−3 dn−2 pn−2 . }
}
   
rep(j,i+1,n) if (A[j][i]) { bn−1 0 0 ··· 0 qn−2 dn−1 xn−1
vd conv(const vd& a, const vd& b) {
b[j] ˆ= b[i];
if (a.empty() || b.empty()) return {};
A[j] ˆ= A[i]; This is useful for solving problems on the type vd res(sz(a) + sz(b) - 1);
}
int L = 32 - __builtin_clz(sz(res)), n = 1 << L;
rank++;
ai = bi ai−1 + ci ai+1 + di , 1 ≤ i ≤ n, vector<C> in(n), out(n), rt(n, 1); vi rev(n);
}
rep(i,0,n) rev[i] = (rev[i/2] | (i&1) << L) / 2;
where a0 , an+1 , bi , ci and di are known. a can then be obtained from for (int k = 2; k < n; k *= 2) {
x = bs();
C z[] = {1, polar(1.0, M_PI / k)};
for (int i = rank; i--;) {
rep(i,k,2*k) rt[i] = rt[i/2] * z[i&1];
if (!b[i]) continue; {ai } = tridiagonal({1, −1, −1, ..., −1, 1}, {0, c1 , c2 , . . . , cn }, }
x[col[i]] = 1;
{b1 , b2 , . . . , bn , 0}, {a0 , d1 , d2 , . . . , dn , an+1 }). copy(all(a), begin(in));
rep(j,0,i) b[j] ˆ= A[j][i];
rep(i,0,sz(b)) in[i].imag(b[i]);
}
Fails if the solution is not unique. fft(in, rt, rev, n);
return rank; // ( multiple solutions i f rank < m)
If |di | > |pi | + |qi−1 | for all i, or |di | > |pi−1 | + |qi |, or the matrix is positive trav(x, in) x *= x;
}
definite, the algorithm is numerically stable and neither tr nor the check for rep(i,0,n) out[i] = in[(n - i) & (n - 1)] - conj(in[i]);
diag[i] == 0 is needed. fft(out, rt, rev, n);
MatrixInverse.h Time: O (N ) 26 lines
rep(i,0,sz(res)) res[i] = imag(out[i]) / (4*n);
Description: Invert matrix A. Returns rank; result is stored in A unless return res;
singular (rank < n). Can easily be extended to prime moduli; for prime typedef double T; }
powers, repeatedly set A−1 = A−1 (2I − AA−1 ) (mod pk ) where A−1 starts vector<T> tridiagonal(vector<T> diag, const vector<T>& super,
as the inverseof A mod p, and k is doubled in each step. const vector<T>& sub, vector<T> b) {
int n = sz(b); vi tr(n); NumberTheoreticTransform.h
Time: O n3 35 lines Description: Can be used for convolutions modulo specific nice primes of
rep(i,0,n-1) {
int matInv(vector<vector<double>>& A) { if (abs(diag[i]) < 1e-9 * abs(super[i])) { // diag [ i ] == 0 the form 2a b + 1, where the convolution result has size at most 2a . For other
int n = sz(A); vi col(n); b[i+1] -= b[i] * diag[i+1] / super[i]; primes/integers, use two different primes and combine with CRT. May return
vector<vector<double>> tmp(n, vector<double>(n)); if (i+2 < n) b[i+2] -= b[i] * sub[i+1] / super[i]; negative values.
rep(i,0,n) tmp[i][i] = 1, col[i] = i; diag[i+1] = sub[i]; tr[++i] = 1; Time: O (N log N )
} else { "ModPow.h" 38 lines

rep(i,0,n) { diag[i+1] -= super[i]*sub[i]/diag[i]; const ll mod = (119 << 23) + 1, root = 3; // = 998244353
KTH FastSubsetTransform ModularArithmetic ModInverse ModPow ModSum ModMulLL ModSqrt eratosthenes 8
// For p < 2ˆ30 there i s also e . g . (5 << 25, 3) , (7 << 26, 3) , 5.1 Modular arithmetic ModMulLL.h
// (479 << 21, 3) and (483 << 21, 5) . The l a s t two are > 10ˆ9. Description: Calculate a · b mod c (or ab mod c) for large c.
Time: O (64/bits · log b), where bits = 64 − k, if we want to deal with k-bit
typedef vector<ll> vl; ModularArithmetic.h numbers. 19 lines
void ntt(ll* x, ll* temp, ll* roots, int N, int skip) { Description: Operators for modular arithmetic. You need to set mod to
if (N == 1) return; typedef unsigned long long ull;
some number first and then you can use the structure. const int bits = 10;
int n2 = N/2; 18 lines
ntt(x , temp, roots, n2, skip*2);
"euclid.h" // i f a l l numbers are l e s s than 2ˆk , set b i t s = 64−k
ntt(x+skip, temp, roots, n2, skip*2); const ll mod = 17; // change to something e l s e const ull po = 1 << bits;
rep(i,0,N) temp[i] = x[i*skip]; struct Mod { ull mod_mul(ull a, ull b, ull &c) {
rep(i,0,n2) { ll x; ull x = a * (b & (po - 1)) % c;
ll s = temp[2*i], t = temp[2*i+1] * roots[skip*i]; Mod(ll xx) : x(xx) {} while ((b >>= bits) > 0) {
x[skip*i] = (s + t) % mod; x[skip*(i+n2)] = (s - t) % mod; Mod operator+(Mod b) { return Mod((x + b.x) % mod); } a = (a << bits) % c;
} Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); } x += (a * (b & (po - 1))) % c;
} Mod operator*(Mod b) { return Mod((x * b.x) % mod); } }
void ntt(vl& x, bool inv = false) { Mod operator/(Mod b) { return *this * invert(b); } return x % c;
ll e = modpow(root, (mod-1) / sz(x)); Mod invert(Mod a) { }
if (inv) e = modpow(e, mod-2); ll x, y, g = euclid(a.x, mod, x, y); ull mod_pow(ull a, ull b, ull mod) {
vl roots(sz(x), 1), temp = roots; assert(g == 1); return Mod((x + mod) % mod); if (b == 0) return 1;
rep(i,1,sz(x)) roots[i] = roots[i-1] * e % mod; } ull res = mod_pow(a, b / 2, mod);
ntt(&x[0], &temp[0], &roots[0], sz(x), 1); Mod operatorˆ(ll e) { res = mod_mul(res, res, mod);
} if (!e) return Mod(1); if (b & 1) return mod_mul(res, a, mod);
vl conv(vl a, vl b) { Mod r = *this ˆ (e / 2); r = r * r; return res;
int s = sz(a) + sz(b) - 1; if (s <= 0) return {}; return e&1 ? *this * r : r; }
int L = s > 1 ? 32 - __builtin_clz(s - 1) : 0, n = 1 << L; }
};
if (s <= 200) { // ( factor 10 optimization for | a | , | b | = 10) ModSqrt.h
vl c(s); Description: Tonelli-Shanks algorithm for modular square roots.
Time: O log2 p worst case, often O (log p)

rep(i,0,sz(a)) rep(j,0,sz(b))
c[i + j] = (c[i + j] + a[i] * b[j]) % mod; ModInverse.h "ModPow.h" 24 lines
return c; Description: Pre-computation of modular inverses. Assumes LIM ≤ mod ll sqrt(ll a, ll p) {
} and that mod is a prime. a %= p; if (a < 0) a += p;
3 lines
a.resize(n); ntt(a); if (a == 0) return 0;
b.resize(n); ntt(b); const ll mod = 1000000007, LIM = 200000;
ll* inv = new ll[LIM] - 1; inv[1] = 1; assert(modpow(a, (p-1)/2, p) == 1);
vl c(n); ll d = modpow(n, mod-2); if (p % 4 == 3) return modpow(a, (p+1)/4, p);
rep(i,0,n) c[i] = a[i] * b[i] % mod * d % mod; rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[mod % i] % mod;
// aˆ(n+3)/8 or 2ˆ(n+3)/8 ∗ 2ˆ(n−1)/4 works i f p % 8 == 5
ntt(c, true); c.resize(s); return c; ll s = p - 1, n = 2;
} int r = 0, m;
ModPow.h 6 lines while (s % 2 == 0)
++r, s /= 2;
const ll mod = 1000000007; // f a s t e r i f const
while (modpow(n, (p - 1) / 2, p) != p - 1) ++n;
ll modpow(ll a, ll e) {
ll x = modpow(a, (s + 1) / 2, p);
FastSubsetTransform.h if (e == 0) return 1;
ll b = modpow(a, s, p), g = modpow(n, s, p);
Description: Transform to a basis with fast convolutions of the form ll x = modpow(a * a % mod, e >> 1);
for (;; r = m) {
X return e & 1 ? x * a % mod : x;
c[z] = a[x] · b[y], where ⊕ is one of AND, OR, XOR. The size }
ll t = b;
z=x⊕y
for (m = 0; m < r && t != 1; ++m)
of a must be a power of two.
t = t * t % p;
Time: O (N log N ) 16 lines if (m == 0) return x;
void FST(vi& a, bool inv) { ModSum.h ll gs = modpow(g, 1LL << (r - m - 1), p);
for (int n = sz(a), step = 1; step < n; step *= 2) { Description: Sums of mod’ed
Pto−1arithmetic progressions. g = gs * gs % p;
for (int i = 0; i < n; i += 2 * step) rep(j,i,i+step) { modsum(to, c, k, m) = i=0 (ki + c)%m. divsum is similar but for x = x * gs % p;
int &u = a[j], &v = a[j + step]; tie(u, v) = floored division. b = b * g % p;
inv ? pii(v - u, u) : pii(v, u + v); // AND Time: log(m), with a large constant. 16 lines }
inv ? pii(v, u - v) : pii(u + v, u); // OR }
typedef unsigned long long ull;
pii(u + v, u - v); // XOR ull sumsq(ull to) { return to / 2 * ((to-1) | 1); }
}
} ull divsum(ull to, ull c, ull k, ull m) {
5.2 Primality
if (inv) trav(x, a) x /= sz(a); // XOR only ull res = k / m * sumsq(to) + c / m * to;
} k %= m; c %= m; eratosthenes.h
vi conv(vi a, vi b) { if (!k) return res; Description: Prime sieve for generating all primes up to a certain limit.
FST(a, 0); FST(b, 0); ull to2 = (to * k + c) / m; isprime[i] is true iff i is a prime.
rep(i,0,sz(a)) a[i] *= b[i]; return res + (to - 1) * to2 - divsum(to2, m-1 - c, m, k); Time: lim=100’000’000 ≈ 0.8 s. Runs 30% faster if only odd indices are
FST(a, 1); return a; } stored.
} 11 lines
const int MAX_PR = 5’000’000;
ll modsum(ull to, ll c, ll k, ll m) {
bitset<MAX_PR> isprime;
c = ((c % m) + m) % m;
vi eratosthenes_sieve(int lim) {
k = ((k % m) + m) % m;
isprime.set(); isprime[0] = isprime[1] = 0;
return to * c + k * sumsq(to) - m * divsum(to, c, k, m);
for (int i = 4; i < lim; i += 2) isprime[i] = 0;
Number theory (5) }
for (int i = 3; i*i < lim; i += 2) if (isprime[i])
KTH MillerRabin factor euclid Euclid phiFunction ContinuedFractions FracBinarySearch 9
for (int j = i*i; j < lim; j += i*2) isprime[j] = 0; 5.3 Divisibility 5.4 Fractions
vi pr;
rep(i,2,lim) if (isprime[i]) pr.push_back(i);
return pr; euclid.h
} Description: Finds the Greatest Common Divisor to the integers a and b.
Euclid also finds two integers x and y, such that ax + by = gcd(a, b). If a
and b are coprime, then x is the inverse of a (mod b).
ContinuedFractions.h
7 lines Description: Given N and a real number x ≥ 0, finds the closest rational
MillerRabin.h ll gcd(ll a, ll b) { return __gcd(a, b); } approximation p/q with p, q ≤ N . It will obey |p/q − x| ≤ 1/qN .
Description: Deterministic Miller-Rabin primality test. Guaranteed to For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . (pk /qk alternates
work for numbers up to 264 ; for larger numbers, extend A randomly. ll euclid(ll a, ll b, ll &x, ll &y) { between > x and < x.) If x is rational, y eventually becomes ∞; if x is the
Time: 7 times the complexity of ab mod c. if (b) { ll d = euclid(b, a % b, y, x); root of a degree 2 polynomial the a’s eventually become cyclic.
"ModMulLL.h" 12 lines return y -= a/b * x, d; } Time: O (log N ) 21 lines
bool isPrime(ull n) { return x = 1, y = 0, a;
} typedef double d; // for N ∼ 1e7 ; long double for N ∼ 1e9
if (n < 2 || n % 6 % 4 != 1) return n - 2 < 2;
pair<ll, ll> approximate(d x, ll N) {
ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; d y = x;
s = __builtin_ctzll(n-1), d = n >> s;
trav(a, A) { // ˆ count t r a i l i n g zeroes Euclid.java for (;;) {
ull p = mod_pow(a, d, n), i = s; Description: Finds {x, y, d} s.t. ax + by = d = gcd(a, b). 11 lines
ll lim = min(P ? (N-LP) / P : inf, Q ? (N-LQ) / Q : inf),
a = (ll)floor(y), b = min(a, lim),
while (p != 1 && p != n - 1 && a % n && i--) static BigInteger[] euclid(BigInteger a, BigInteger b) { NP = b*P + LP, NQ = b*Q + LQ;
p = mod_mul(p, p, n); BigInteger x = BigInteger.ONE, yy = x; if (a > b) {
if (p != n-1 && i != s) return 0; BigInteger y = BigInteger.ZERO, xx = y; // I f b > a/2, we have a semi−convergent that gives us a
} while (b.signum() != 0) { // better approximation ; i f b = a/2, we ∗may∗ have one .
return 1; BigInteger q = a.divide(b), t = b; // Return {P, Q} here for a more canonical approximation .
} b = a.mod(b); a = t; return (abs(x - (d)NP / (d)NQ) < abs(x - (d)P / (d)Q)) ?
t = xx; xx = x.subtract(q.multiply(xx)); x = t; make_pair(NP, NQ) : make_pair(P, Q);
t = yy; yy = y.subtract(q.multiply(yy)); y = t; }
factor.h } if (abs(y = 1/(y - (d)a)) > 3*N) {
Description: Pollard’s rho algorithm. It is a probabilistic factorisation al- return new BigInteger[]{x, y, a}; return {NP, NQ};
gorithm, whose expected time complexity is good. Before you start using it, } }
run init(bits), where bits is the length of the numbers you use. Returns LP = P; P = NP;
factors of the input without duplicates. LQ = Q; Q = NQ;
Time: Expected running time should be good enough for 50-bit numbers. 5.3.1 Bézout’s identity }
"ModMulLL.h", "MillerRabin.h", "eratosthenes.h" 35 lines
}
vector<ull> pr; For a 6=, b 6= 0, then d = gcd(a, b) is the smallest positive
ull f(ull a, ull n, ull &has) {
return (mod_mul(a, a, n) + has) % n; integer for which there are integer solutions to
}
vector<ull> factor(ull d) { FracBinarySearch.h
vector<ull> res; ax + by = d
Description: Given f and N , finds the smallest fraction p/q ∈ [0, 1] such
for (int i = 0; i < sz(pr) && pr[i]*pr[i] <= d; i++) that f (p/q) is true, and p, q ≤ N . You may want to throw an exception from
if (d % pr[i] == 0) { f if it finds an exact solution, in which case N can be removed.
while (d % pr[i] == 0) d /= pr[i]; If (x, y) is one solution, then all solutions are given by
Usage: fracBS([](Frac f) { return f.p>=3*f.q; }, 10); // {1,3}
res.push_back(pr[i]); Time: O (log(N ))
}   24 lines

//d i s now a product of at most 2 primes . kb ka struct Frac { ll p, q; };


if (d > 1) {
x+ ,y − , k∈Z
gcd(a, b) gcd(a, b)
if (prime(d)) template<class F>
res.push_back(d); Frac fracBS(F f, ll N) {
else while (true) { bool dir = 1, A = 1, B = 1;
ull has = rand() % 2321 + 47; phiFunction.h Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to search (0 , N]
ull x = 2, y = 2, c = 1; Description: Euler’s totient or Euler’s phi function is defined as φ(n) := # assert(!f(lo)); assert(f(hi));
for (; c==1; c = __gcd((y > x ? y - x : x - y), d)) { of positive integers ≤ n that are coprime with n. The cototient is n − φ(n). while (A || B) {
x = f(x, d, has); φ(1) = 1, p prime ⇒ φ(pk ) = (p − 1)pk−1 , m, n coprime ⇒ φ(mn) = ll adv = 0, step = 1; // move hi i f dir , e l s e lo
y = f(f(y, d, has), d, has); k k r then φ(n) = (p − 1)pk1 −1 ...(p − 1)pkr −1 .
for (int si = 0; step; (step *= 2) >>= si) {
} φ(m)φ(n). Q If n = p1 1 p2 2 ...pk
r 1 1 r r adv += step;
if (c != d) { φ(n) = n · p|n (1 − 1/p). Frac mid{lo.p * adv + hi.p, lo.q * adv + hi.q};
P P
res.push_back(c); d /= c; d|n φ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nφ(n)/2, n > 1 if (abs(mid.p) > N || mid.q > N || dir == !f(mid)) {
if (d != c) res.push_back(d); Euler’s thm: a, n coprime ⇒ aφ(n) ≡ 1 (mod n). adv -= step; si = 2;
break; Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 (mod p) ∀a. }
} 8 lines }
} const int LIM = 5000000; hi.p += lo.p * adv;
} int phi[LIM]; hi.q += lo.q * adv;
return res; dir = !dir;
} void calculatePhi() { swap(lo, hi);
void init(int bits) {//how many b i t s do we use? rep(i,0,LIM) phi[i] = i&1 ? i : i/2; A = B; B = !!adv;
vi p = eratosthenes_sieve(1 << ((bits + 2) / 3)); for(int i = 3; i < LIM; i += 2) if(phi[i] == i) }
pr.assign(all(p)); for(int j = i; j < LIM; j += i) phi[j] -= phi[j] / i; return dir ? hi : lo;
} } }
KTH chinese IntPerm binomialModPrime multinomial 10
5.5 Chinese remainder theorem 6.1 Permutations 6.2 Partitions and subsets
chinese.h 6.1.1 Factorial 6.2.1 Partition function
Description: Chinese Remainder Theorem.
chinese(a, m, b, n) returns a number x, such that x ≡ a (mod m) and n 123 4 5 6 7 8 9 10
Number of ways of writing n as a sum of positive integers,
x ≡ b (mod n). For not coprime n, m, use chinese common. Note that all n! 1 2 6 24 120 720 5040 40320 362880 3628800 disregarding the order of the summands.
numbers must be less than 231 if you have Z = unsigned long long.
Time: log(m + n) n 11 12 13 14 15 16 17
"euclid.h" 13 lines n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14 p(0) = 1, p(n) =
X
(−1)k+1 p(n − k(3k − 1)/2)
template<class Z> Z chinese(Z a, Z m, Z b, Z n) {
Z x, y; euclid(m, n, x, y);
n 20 25 30 40 50 100 150 171
k∈Z\{0}
Z ret = a * (y + m) % m * n + b * (x + n) % n * m; n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL MAX
if (ret >= m * n) ret -= m * n; √
return ret; IntPerm.h p(n) ∼ 0.145/n · exp(2.56 n)
} Description: Permutation -> integer conversion. (Not order preserving.)
Time: O (n)
template<class Z> Z chinese_common(Z a, Z m, Z b, Z n) { 6 lines n 0 1 2 3 4 5 6 7 8 9 20 50 100
int permToInt(vi& v) {
Z d = gcd(m, n);
int use = 0, i = 0, r = 0;
p(n) 1 1 2 3 5 7 11 15 22 30 627 ∼2e5 ∼2e8
if (((b -= a) %= n) < 0) b += n;
if (b % d) return -1; // No solution trav(x, v) r = r * ++i + __builtin_popcount(use & -(1 << x)),
return d * chinese(Z(0), m/d, b/d, n/d) + a; use |= 1 << x; // (note : minus, not ∼! ) 6.2.2 Binomials
} return r;
}
binomialModPrime.h
Description: Lucas’ thm: Let n, m be non-negative integers and p a prime.
Write nQ= nk pk + ... + n1 p + n0 and m = mk pk + ... + m1 p + m0 . Then
5.6 Pythagorean Triples 6.1.2 Cycles n
≡ k ni
(mod p). fact and invfact must hold pre-computed facto-
m i=0 mi
rials / inverse factorials, e.g. from ModInverse.h.
Let gS (n) be the number of n-permutations whose cycle Time: O logp n

The Pythagorean triples are uniquely generated by 10 lines
lengths all belong to the set S. Then ll chooseModP(ll n, ll m, int p, vi& fact, vi& invfact) {
ll c = 1;
2 2 2 2 ∞
!
a = k · (m − n ), b = k · (2mn), c = k · (m + n ), X xn X xn while (n || m) {
gS (n) = exp ll a = n % p, b = m % p;
n=0
n! n if (a < b) return 0;
n∈S
with m > n > 0, k > 0, m⊥n, and either m or n even. c = c * fact[a] % p * invfact[b] % p * invfact[a - b] % p;
n /= p; m /= p;
}
6.1.3 Derangements return c;
5.7 Primes }
Permutations of a set such that none of the elements appear
p = 962592769 is such that 2 | p − 1, which may be useful. in their original position.
21 multinomial.h P
  Description: Computes k1 + · · · + kn = ( ki )!
 
For hashing use 970592641 (31-bit number), 31443539979727 .
n n! k 1 , k 2 , . . . , kn k1 !k2 !...kn ! 6 lines
(45-bit), 3006703054056749 (52-bit). There are 78498 primes D(n) = (n−1)(D(n−1)+D(n−2)) = nD(n−1)+(−1) = e ll multinomial(vi& v) {
less than 1 000 000. ll c = 1, m = v.empty() ? 1 : v[0];
rep(i,1,sz(v)) rep(j,0,v[i])
c = c * ++m / (j+1);
Primitive roots exist modulo any prime power pa , except for 6.1.4 Burnside’s lemma return c;
}
p = 2, a > 2, and there are φ(φ(pa )) many. For p = 2, a > 2, Given a group G of symmetries and a set X, the number of
the group Z×2a is instead isomorphic to Z2 × Z2a−2 . elements of X up to symmetry equals
6.3 General purpose numbers
1 X g
|X |,
5.8 Estimates |G| 6.3.1 Stirling numbers of the first kind
g∈G
Number of permutations on n items with k cycles.
P
d|n d = O(n log log n). where X g are the elements fixed by g (g.x = x).
The number of divisors of n is at most around 100 for If f (n) counts “configurations” (of some sort) of length n, we c(n, k) = c(n − 1, k − 1) + (n − 1)c(n − 1, k), c(0, 0) = 1
n < 5e4, 500 for n < 1e7, 2000 for n < 1e10, 200 000 for can ignore rotational symmetry using G = Zn to get Pn k
k=0 c(n, k)x = x(x + 1) . . . (x + n − 1)
n < 1e19. n−1
1X 1X c(8, k) = 8, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1
g(n) = f (gcd(n, k)) = f (k)φ(n/k).
Combinatorial (6) n n c(n, 2) = 0, 0, 1, 3, 11, 50, 274, 1764, 13068, 109584, . . .
k=0 k|n
KTH bellmanFord FloydWarshall TopoSort EulerWalk PushRelabel 11
6.3.2 Eulerian numbers Graph (7) vi indeg(n);
rep(i,0,n)
Number of permutations π ∈ Sn in which exactly k elements 7.1 Fundamentals trav(e, edges[i])
indeg[e]++;
are greater than the previous element. k j:s s.t. queue<int> q; // use priority queue for l e x i c . smallest ans .
π(j) > π(j + 1), k + 1 j:s s.t. π(j) ≥ j, k j:s s.t. bellmanFord.h rep(i,0,n) if (indeg[i] == 0) q.push(-i);
Description: Calculates shortest path in a graph that might have negative int nr = 0;
π(j) > j. edge distances. Propagates negative infinity distances (sets dist = -inf), and while (q.size() > 0) {
returns true if there is some negative cycle. Unreachable nodes get dist = int i = -q.front(); // top () for priority queue
idx[i] = nr++;
E(n, k) = (n − k)E(n − 1, k − 1) + (k + 1)E(n − 1, k) inf.
q.pop();
Time: O (EV ) 27 lines trav(e, edges[i])
E(n, 0) = E(n, n − 1) = 1 typedef ll T; // or whatever if (--indeg[e] == 0) q.push(-e);
struct Edge { int src, dest; T weight; }; }
k   struct Node { T dist; int prev; }; return nr == n;
X n+1 struct Graph { vector<Node> nodes; vector<Edge> edges; }; }
E(n, k) = (−1)j (k + 1 − j)n
j=0
j const T inf = numeric_limits<T>::max();
bool bellmanFord2(Graph& g, int start_node) {
trav(n, g.nodes) { n.dist = inf; n.prev = -1; }
7.2 Euler walk
6.3.3 Stirling numbers of the second kind g.nodes[start_node].dist = 0;
EulerWalk.h
Partitions of n distinct elements into exactly k rep(i,0,sz(g.nodes)) trav(e, g.edges) { Description: Eulerian undirected/directed path/cycle algorithm. Returns
Node& cur = g.nodes[e.src]; a list of nodes in the Eulerian path/cycle with src at both start and end,
groups. Node& dest = g.nodes[e.dest]; or empty list if no cycle/path exists. To get edge indices back, also put
if (cur.dist == inf) continue; it->second in s (and then ret).
S(n, k) = S(n − 1, k − 1) + kS(n − 1, k) T ndist = cur.dist + (cur.dist == -inf ? 0 : e.weight); Time: O (E) where E is the number of edges. 27 lines
if (ndist < dest.dist) {
dest.prev = e.src; struct V {
vector<pii> outs; // ( dest , edge index )
S(n, 1) = S(n, n) = 1 dest.dist = (i >= sz(g.nodes)-1 ? -inf : ndist);
int nins = 0;
}
k   } };
1 X k−j k
S(n, k) = (−1) jn bool ret = 0;
vi euler_walk(vector<V>& nodes, int nedges, int src=0) {
k! j=0 j rep(i,0,sz(g.nodes)) trav(e, g.edges) {
int c = 0;
if (g.nodes[e.src].dist == -inf)
g.nodes[e.dest].dist = -inf, ret = 1; trav(n, nodes) c += abs(n.nins - sz(n.outs));
} if (c > 2) return {};
6.3.4 Bell numbers return ret; vector<vector<pii>::iterator> its;
} trav(n, nodes)
Total number of partitions of n distinct elements. B(n) = its.push_back(n.outs.begin());
vector<bool> eu(nedges);
1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, . . . . For p prime, FloydWarshall.h vi ret, s = {src};
Description: Calculates all-pairs shortest path in a directed graph that while(!s.empty()) {
B(pm + n) ≡ mB(n) + B(n + 1) (mod p) might have negative edge distances. Input is an distance matrix m, where
m[i][j] = inf if i and j are not adjacent. As output, m[i][j] is set to the
int x = s.back();
auto& it = its[x], end = nodes[x].outs.end();
shortest distance between i and j, inf if no path, or -inf if the path goes while(it != end && eu[it->second]) ++it;
through a negative-weight cycle. if(it == end) { ret.push_back(x); s.pop_back(); }
6.3.5 Catalan numbers Time: O N 3

12 lines
else { s.push_back(it->first); eu[it->second] = true; }
}
const ll inf = 1LL << 62; if(sz(ret) != nedges+1)
      void floydWarshall(vector<vector<ll>>& m) { ret.clear(); // No Eulerian cycles/paths .
1 2n 2n 2n (2n)! int n = sz(m);
Cn = = − = rep(i,0,n) m[i][i] = min(m[i][i], {});
// else , non−cycle i f ret . front () != ret . back ()
n+1 n n n+1 (n + 1)!n! rep(k,0,n) rep(i,0,n) rep(j,0,n)
reverse(all(ret));
return ret;
if (m[i][k] != inf && m[k][j] != inf) {
2(2n + 1) X
auto newDist = max(m[i][k] + m[k][j], -inf);
}
C0 = 1, Cn+1 = Cn , Cn+1 = Ci Cn−i
n+2 m[i][j] = min(m[i][j], newDist);
}
Cn = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, . . . rep(k,0,n) if (m[k][k] < 0) rep(i,0,n) rep(j,0,n) 7.3 Network flow
if (m[i][k] != inf && m[k][j] != inf) m[i][j] = -inf;
• sub-diagonal monotone paths in an n × n grid. } PushRelabel.h
Description: Push-relabel using the highest label selection rule and the gap
• strings with n pairs of parenthesis, correctly nested. heuristic. Quite fast in practice. To obtain the actual flow, look at positive
• binary trees with with n + 1 leaves (0 or 2 children). TopoSort.h
Description: Topological sorting. Given is an oriented graph. Output is an values only.  √ 
2
• ordered trees with n + 1 vertices. ordering of vertices (array idx), such that there are edges only from left to Time: O V E
51 lines
right. The function returns false if there is a cycle in the graph.
• ways a convex polygon with n + 2 sides can be cut into Time: O (|V | + |E|) typedef ll Flow;
18 lines struct Edge {
triangles by connecting vertices with straight lines. template<class E, class I> int dest, back;
• permutations of [n] with no 3-term increasing subseq. bool topo_sort(const E &edges, I &idx, int n) { Flow f, c;
KTH MinCostMaxFlow EdmondsKarp MinCut GlobalMinCut 12
}; N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap), EdmondsKarp.h
seen(N), dist(N), pi(N), par(N) {} Description: Flow algorithm with guaranteed complexity O(V E 2 ). To get
struct PushRelabel { edge flow values, compare capacities before and after, and take the positive
vector<vector<Edge>> g; void addEdge(int from, int to, ll cap, ll cost) { values only. 35 lines
vector<Flow> ec; this->cap[from][to] = cap;
vector<Edge*> cur; this->cost[from][to] = cost; template<class T> T edmondsKarp(vector<unordered_map<int, T>>&
vector<vi> hs; vi H; ed[from].push_back(to); graph, int source, int sink) {
PushRelabel(int n) : g(n), ec(n), cur(n), hs(2*n), H(n) {} red[to].push_back(from); assert(source != sink);
} T flow = 0;
void add_edge(int s, int t, Flow cap, Flow rcap=0) { vi par(sz(graph)), q = par;
if (s == t) return; void path(int s) {
Edge a = {t, sz(g[t]), 0, cap}; fill(all(seen), 0); for (;;) {
Edge b = {s, sz(g[s]), 0, rcap}; fill(all(dist), INF); fill(all(par), -1);
g[s].push_back(a); dist[s] = 0; ll di; par[source] = 0;
g[t].push_back(b); int ptr = 1;
} __gnu_pbds::priority_queue<pair<ll, int>> q; q[0] = source;
vector<decltype(q)::point_iterator> its(N);
void add_flow(Edge& e, Flow f) { q.push({0, s}); rep(i,0,ptr) {
Edge &back = g[e.dest][e.back]; int x = q[i];
if (!ec[e.dest] && f) hs[H[e.dest]].push_back(e.dest); auto relax = [&](int i, ll cap, ll cost, int dir) { trav(e, graph[x]) {
e.f += f; e.c -= f; ec[e.dest] += f; ll val = di - pi[i] + cost; if (par[e.first] == -1 && e.second > 0) {
back.f -= f; back.c += f; ec[back.dest] -= f; if (cap && val < dist[i]) { par[e.first] = x;
} dist[i] = val; q[ptr++] = e.first;
Flow maxflow(int s, int t) { par[i] = {s, dir}; if (e.first == sink) goto out;
int v = sz(g); H[s] = v; ec[t] = 1; if (its[i] == q.end()) its[i] = q.push({-dist[i], i}); }
vi co(2*v); co[0] = v-1; else q.modify(its[i], {-dist[i], i}); }
rep(i,0,v) cur[i] = g[i].data(); } }
trav(e, g[s]) add_flow(e, e.c); }; return flow;
out:
for (int hi = 0;;) { while (!q.empty()) { T inc = numeric_limits<T>::max();
while (hs[hi].empty()) if (!hi--) return -ec[s]; s = q.top().second; q.pop(); for (int y = sink; y != source; y = par[y])
int u = hs[hi].back(); hs[hi].pop_back(); seen[s] = 1; di = dist[s] + pi[s]; inc = min(inc, graph[par[y]][y]);
while (ec[u] > 0) // discharge u trav(i, ed[s]) if (!seen[i])
if (cur[u] == g[u].data() + sz(g[u])) { relax(i, cap[s][i] - flow[s][i], cost[s][i], 1); flow += inc;
H[u] = 1e9; trav(i, red[s]) if (!seen[i]) for (int y = sink; y != source; y = par[y]) {
trav(e, g[u]) if (e.c && H[u] > H[e.dest]+1) relax(i, flow[i][s], -cost[i][s], 0); int p = par[y];
H[u] = H[e.dest]+1, cur[u] = &e; } if ((graph[p][y] -= inc) <= 0) graph[p].erase(y);
if (++co[H[u]], !--co[hi] && hi < v) rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF); graph[y][p] += inc;
rep(i,0,v) if (hi < H[i] && H[i] < v) } }
--co[H[i]], H[i] = v + 1; }
hi = H[u]; pair<ll, ll> maxflow(int s, int t) { }
} else if (cur[u]->c && H[u] == H[cur[u]->dest]+1) ll totflow = 0, totcost = 0;
add_flow(*cur[u], min(ec[u], cur[u]->c)); while (path(s), seen[t]) { MinCut.h
else ++cur[u]; ll fl = INF; Description: After running max-flow, the left side of a min-cut from s to t
} for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) is given by all vertices reachable from s, only traversing edges with positive
} fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]); residual capacity.
}; totflow += fl;
for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p)
if (r) flow[p][x] += fl;
MinCostMaxFlow.h else flow[x][p] -= fl; GlobalMinCut.h
Description: Min-cost max-flow. cap[i][j] != cap[j][i] is allowed; double } Description: Find a global minimum cut in an undirected graph, as repre-
edges are not. If costs can be negative, call setpi before maxflow, but note rep(i,0,N) rep(j,0,N) totcost += cost[i][j] * flow[i][j]; sented by an adjacency matrix.
Time: O V 3

that negative cost cycles are not supported. To obtain the actual flow, look return {totflow, totcost}; 31 lines
at positive values only. }
Time: Approximately O E 2
 pair<int, vi> GetMinCut(vector<vi>& weights) {
81 lines int N = sz(weights);
// I f some costs can be negative , c a l l t h i s before maxflow :
#include <bits/extc++.h> vi used(N), cut, best_cut;
void setpi(int s) { // ( otherwise , leave t h i s out)
int best_weight = -1;
fill(all(pi), INF); pi[s] = 0;
const ll INF = numeric_limits<ll>::max() / 4;
int it = N, ch = 1; ll v;
typedef vector<ll> VL; for (int phase = N-1; phase >= 0; phase--) {
while (ch-- && it--)
vi w = weights[0], added = used;
rep(i,0,N) if (pi[i] != INF)
struct MCMF { int prev, k = 0;
trav(to, ed[i]) if (cap[i][to])
int N; rep(i,0,phase){
if ((v = pi[i] + cost[i][to]) < pi[to])
vector<vi> ed, red; prev = k;
pi[to] = v, ch = 1;
vector<VL> cap, flow, cost; k = -1;
assert(it >= 0); // negative cost cycle
vi seen; rep(j,1,N)
}
VL dist, pi; if (!added[j] && (k == -1 || w[j] > w[k])) k = j;
};
vector<pii> par; if (i == phase-1) {
rep(j,0,N) weights[prev][j] += weights[k][j];
MCMF(int N) : rep(j,0,N) weights[j][prev] = weights[prev][j];
KTH hopcroftKarp DFSMatching WeightedMatching GeneralMatching 13
used[k] = true; DFSMatching.h fill(all(seen), 0);
cut.push_back(k); Description: This is a simple matching algorithm but should be just fine rep(k,0,n)
if (best_weight == -1 || w[k] < best_weight) { in most cases. Graph g should be a list of neighbours of the left partition. dist[k] = cost[s][k] - u[s] - v[k];
best_cut = cut; n is the size of the left partition and m is the size of the right partition. If
best_weight = w[k]; you want to get the matched pairs, match[i] contains match for vertex i on int j = 0;
} the right side or −1 if it’s not matched. for (;;) {
} else { Time: O (EV ) where E is the number of edges and V is the number of j = -1;
rep(j,0,N) vertices. 24 lines
rep(k,0,n){
w[j] += weights[k][j]; if (seen[k]) continue;
added[k] = true; vi match; if (j == -1 || dist[k] < dist[j]) j = k;
} vector<bool> seen; }
} bool find(int j, const vector<vi>& g) { seen[j] = 1;
} if (match[j] == -1) return 1; int i = R[j];
return {best_weight, best_cut}; seen[j] = 1; int di = match[j]; if (i == -1) break;
} trav(e, g[di]) rep(k,0,n) {
if (!seen[e] && find(e, g)) { if (seen[k]) continue;
match[e] = di; auto new_dist = dist[j] + cost[i][k] - u[i] - v[k];
7.4 Matching }
return 1; if (dist[k] > new_dist) {
dist[k] = new_dist;
return 0; dad[k] = j;
hopcroftKarp.h } }
Description: Find a maximum matching in a bipartite graph. int dfs_matching(const vector<vi>& g, int n, int m) {
Usage: vi ba(m, }
√  -1); hopcroftKarp(g, ba); match.assign(m, -1); }
Time: O VE rep(i,0,n) {
45 lines
seen.assign(m, 0); rep(k,0,n) {
bool dfs(int a, int layer, const vector<vi>& g, vi& btoa, trav(j,g[i]) if (k == j || !seen[k]) continue;
vi& A, vi& B) { if (find(j, g)) { auto w = dist[k] - dist[j];
if (A[a] != layer) return 0; match[j] = i; v[k] += w, u[R[k]] -= w;
A[a] = -1; break; }
trav(b, g[a]) if (B[b] == layer + 1) { } u[s] += dist[j];
B[b] = -1; }
if (btoa[b] == -1 || dfs(btoa[b], layer+2, g, btoa, A, B)) return m - (int)count(all(match), -1); while (dad[j] >= 0) {
return btoa[b] = a, 1; } int d = dad[j];
}
R[j] = R[d];
return 0;
L[R[j]] = j;
} WeightedMatching.h j = d;
Description: Min cost bipartite matching. Negate costs for max cost. }
int hopcroftKarp(const vector<vi>& g, vi& btoa) { Time: O N 3 75 lines R[j] = s;
int res = 0;
L[s] = j;
vi A(g.size()), B(btoa.size()), cur, next; typedef vector<double> vd;
}
for (;;) { bool zero(double x) { return fabs(x) < 1e-10; }
auto value = vd(1)[0];
fill(all(A), 0); double MinCostMatching(const vector<vd>& cost, vi& L, vi& R) {
rep(i,0,n) value += cost[i][L[i]];
fill(all(B), -1); int n = sz(cost), mated = 0;
return value;
cur.clear(); vd dist(n), u(n), v(n);
}
trav(a, btoa) if(a != -1) A[a] = -1; vi dad(n), seen(n);
rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a);
for (int lay = 1;; lay += 2) { rep(i,0,n) {
bool islast = 0; u[i] = cost[i][0]; GeneralMatching.h
next.clear(); rep(j,1,n) u[i] = min(u[i], cost[i][j]); Description: Matching for general graphs. Fails with probability N/mod.
trav(a, cur) trav(b, g[a]) { } Time: O N 3
if (btoa[b] == -1) { rep(j,0,n) { "../numerical/MatrixInverse-mod.h" 40 lines

B[b] = lay; v[j] = cost[0][j] - u[0]; vector<pii> generalMatching(int N, vector<pii>& ed) {


islast = 1; rep(i,1,n) v[j] = min(v[j], cost[i][j] - u[i]); vector<vector<ll>> mat(N, vector<ll>(N)), A;
} } trav(pa, ed) {
else if (btoa[b] != a && B[b] == -1) { int a = pa.first, b = pa.second, r = rand() % mod;
B[b] = lay; L = R = vi(n, -1); mat[a][b] = r, mat[b][a] = (mod - r) % mod;
next.push_back(btoa[b]); rep(i,0,n) rep(j,0,n) { }
} if (R[j] != -1) continue;
} if (zero(cost[i][j] - u[i] - v[j])) { int r = matInv(A = mat), M = 2*N - r, fi, fj;
if (islast) break; L[i] = j; assert(r % 2 == 0);
if (next.empty()) return res; R[j] = i;
trav(a, next) A[a] = lay+1; mated++; if (M != N) do {
cur.swap(next); break; mat.resize(M, vector<ll>(M));
} } rep(i,0,N) {
rep(a,0,sz(g)) { } mat[i].resize(M);
if(dfs(a, 0, g, btoa, A, B)) rep(j,N,M) {
++res; for (; mated < n; mated++) { // u n t i l solution i s f e a s i b l e int r = rand() % mod;
} int s = 0; mat[i][j] = r, mat[j][i] = (mod - r) % mod;
} while (L[s] != -1) s++; }
} fill(all(dad), -1); }
KTH MinimumVertexCover SCC BiconnectedComponents 2sat 14
} while (matInv(A = mat) != M); if (low == val[j]) { 2sat.h
do { Description: Calculates a valid assignment to boolean variables a,
vi has(M, 1); vector<pii> ret; x = z.back(); z.pop_back(); b, c,... to a 2-SAT problem, so that an expression of the type
rep(it,0,M/2) { comp[x] = ncomps; (akkb)&&(!akkc)&&(dkk!b)&&... becomes true, or reports that it is unsatis-
rep(i,0,M) if (has[i]) cont.push_back(x); fiable. Negated variables are represented by bit-inversions (∼x).
rep(j,i+1,M) if (A[i][j] && mat[i][j]) { } while (x != j); Usage: TwoSat ts(number of boolean variables);
fi = i; fj = j; goto done; f(cont); cont.clear(); ts.either(0, ∼3); // Var 0 is true or var 3 is false
} assert(0); done: ncomps++; ts.set value(2); // Var 2 is true
if (fj < N) ret.emplace_back(fi, fj); } ts.at most one({0,∼1,2}); // <= 1 of vars 0, ∼1 and 2 are true
has[fi] = has[fj] = 0; return val[j] = low; ts.solve(); // Returns true iff it is solvable
rep(sw,0,2) { } ts.values[0..N-1] holds the assigned values to the vars
ll a = modpow(A[fi][fj], mod-2); template<class G, class F> void scc(G& g, F f) { Time: O (N + E), where N is the number of boolean variables, and E is the
rep(i,0,M) if (has[i] && A[i][fj]) { int n = sz(g); number of clauses. 57 lines
ll b = A[i][fj] * a % mod; val.assign(n, 0); comp.assign(n, -1);
rep(j,0,M) A[i][j] = (A[i][j] - A[fi][j] * b) % mod; Time = ncomps = 0; struct TwoSat {
} rep(i,0,n) if (comp[i] < 0) dfs(i, g, f); int N;
swap(fi,fj); } vector<vi> gr;
} vi values; // 0 = false , 1 = true
}
return ret; BiconnectedComponents.h TwoSat(int n = 0) : N(n), gr(2*n) {}
} Description: Finds all biconnected components in an undirected graph, and
runs a callback for the edges in each. In a biconnected component there are int add_var() { // ( optional )
at least two distinct paths between any two nodes. Note that a node can be gr.emplace_back();
MinimumVertexCover.h in several components. An edge which is not in a component is a bridge, i.e., gr.emplace_back();
Description: Finds a minimum vertex cover in a bipartite graph. The size not part of any cycle. return N++;
is the same as the size of a maximum matching, and the complement is an Usage: int eid = 0; ed.resize(N); }
independent set. for each edge (a,b) {
"DFSMatching.h" 20 lines ed[a].emplace back(b, eid); void either(int f, int j) {
vi cover(vector<vi>& g, int n, int m) { ed[b].emplace back(a, eid++); } f = max(2*f, -1-2*f);
int res = dfs_matching(g, n, m); bicomps([&](const vi& edgelist) {...}); j = max(2*j, -1-2*j);
seen.assign(m, false); Time: O (E + V ) gr[f].push_back(jˆ1);
33 lines
vector<bool> lfound(n, true); gr[j].push_back(fˆ1);
vi num, st; }
trav(it, match) if (it != -1) lfound[it] = false;
vector<vector<pii>> ed; void set_value(int x) { either(x, x); }
vi q, cover;
int Time;
rep(i,0,n) if (lfound[i]) q.push_back(i);
template<class F> void at_most_one(const vi& li) { // ( optional )
while (!q.empty()) {
int dfs(int at, int par, F f) { if (sz(li) <= 1) return;
int i = q.back(); q.pop_back();
int me = num[at] = ++Time, e, y, top = me; int cur = ∼li[0];
lfound[i] = 1;
trav(pa, ed[at]) if (pa.second != par) { rep(i,2,sz(li)) {
trav(e, g[i]) if (!seen[e] && match[e] != -1) {
tie(y, e) = pa; int next = add_var();
seen[e] = true;
if (num[y]) { either(cur, ∼li[i]);
q.push_back(match[e]);
top = min(top, num[y]); either(cur, next);
}
if (num[y] < me) either(∼li[i], next);
}
st.push_back(e); cur = ∼next;
rep(i,0,n) if (!lfound[i]) cover.push_back(i);
} else { }
rep(i,0,m) if (seen[i]) cover.push_back(n+i);
int si = sz(st); either(cur, ∼li[1]);
assert(sz(cover) == res);
int up = dfs(y, e, f); }
return cover;
top = min(top, up);
}
if (up == me) { vi val, comp, z; int time = 0;
st.push_back(e); int dfs(int i) {
f(vi(st.begin() + si, st.end())); int low = val[i] = ++time, x; z.push_back(i);
7.5 DFS algorithms st.resize(si); trav(e, gr[i]) if (!comp[e])
} low = min(low, val[e] ?: dfs(e));
SCC.h else if (up < me) st.push_back(e); ++time;
Description: Finds strongly connected components in a directed graph. If else { /∗ e i s a bridge ∗/ } if (low == val[i]) do {
vertices u, v belong to the same component, we can reach u from v and vice } x = z.back(); z.pop_back();
versa. } comp[x] = time;
Usage: scc(graph, [&](vi& v) { ... }) visits all components return top; if (values[x>>1] == -1)
in reverse topological order. comp[i] holds the component } values[x>>1] = x&1;
index of a node (a component only has edges to components with } while (x != i);
lower index). ncomps will contain the number of components. template<class F> return val[i] = low;
Time: O (E + V ) void bicomps(F f) { }
24 lines num.assign(sz(ed), 0);
vi val, comp, z, cont; rep(i,0,sz(ed)) if (!num[i]) dfs(i, -1, f); bool solve() {
int Time, ncomps; } values.assign(N, -1);
template<class G, class F> int dfs(int j, G& g, F f) { val.assign(2*N, 0); comp = val;
int low = val[j] = ++Time, x; z.push_back(j); rep(i,0,2*N) if (!comp[i]) dfs(i);
trav(e,g[j]) if (comp[e] < 0) rep(i,0,N) if (comp[2*i] == comp[2*i+1]) return 0;
low = min(low, val[e] ?: dfs(e,g,f)); return 1;
KTH MaximalCliques TreePower LCA CompressTree HLD 15
} Time: O (N log N + Q) HLD.h
}; "../data-structures/RMQ.h" 37 lines Description: Decomposes a tree into vertex disjoint heavy paths and light
typedef vector<pii> vpi; edges such that the path from any leaf to the root contains at most log(n)
typedef vector<vpi> graph; light edges. The function of the HLD can be changed by modifying T, LOW
and f. f is assumed to be associative and commutative.
7.6 Heuristics Usage: HLD hld(G);
struct LCA {
vi time; hld.update(index, value);
MaximalCliques.h vector<ll> dist; tie(value, lca) = hld.query(n1, n2);
Description: Runs a callback for all maximal cliques in a graph (given as a RMQ<pii> rmq; "../data-structures/SegmentTree.h" 93 lines
symmetric bitset matrix; self-edges not allowed). Possible optimization: on typedef vector<pii> vpi;
the top-most recursion level, ignore ’cands’, and go through nodes in order LCA(graph& C) : time(sz(C), -99), dist(sz(C)), rmq(dfs(C)) {}
of increasing
 degree,
 where degrees go down as nodes are removed. struct Node {
Time: O 3n/3 , much faster for sparse graphs vpi dfs(graph& C) { int d, par, val, chain = -1, pos = -1;
12 lines
vector<tuple<int, int, int, ll>> q(1); };
typedef bitset<128> B; vpi ret;
template<class F> int T = 0, v, p, d; ll di; struct Chain {
void cliques(vector<B>& eds, F f, B P = ∼B(), B X={}, B R={}) { while (!q.empty()) { int par, val;
if (!P.any()) { if (!X.any()) f(R); return; } tie(v, p, d, di) = q.back(); vector<int> nodes;
auto q = (P | X)._Find_first(); q.pop_back(); Tree tree;
auto cands = P & ∼eds[q]; if (d) ret.emplace_back(d, p); };
rep(i,0,sz(eds)) if (cands[i]) { time[v] = T++;
R[i] = 1; dist[v] = di; struct HLD {
cliques(eds, f, P & eds[i], X & eds[i], R); trav(e, C[v]) if (e.first != p) typedef int T;
R[i] = P[i] = 0; X[i] = 1; q.emplace_back(e.first, v, d+1, di + e.second); const T LOW = -(1<<29);
} } void f(T& a, T b) { a = max(a, b); }
} return ret;
} vector<Node> V;
vector<Chain> C;
7.7 Trees int query(int a, int b) {
if (a == b) return a; HLD(vector<vpi>& g) : V(sz(g)) {
a = time[a], b = time[b]; dfs(0, -1, g, 0);
TreePower.h return rmq.query(min(a, b), max(a, b)).second; trav(c, C) {
Description: Calculate power of two jumps in a tree, to support fast upward } c.tree = {sz(c.nodes), 0};
jumps and LCAs. Assumes the root node points to itself. ll distance(int a, int b) { for (int ni : c.nodes)
Time: construction O (N log N ), queries O (log N ) 25 lines
int lca = query(a, b); c.tree.update(V[ni].pos, V[ni].val);
return dist[a] + dist[b] - 2 * dist[lca]; }
vector<vi> treeJump(vi& P){ } }
int on = 1, d = 1; };
while(on < sz(P)) on *= 2, d++; void update(int node, T val) {
vector<vi> jmp(d, P); Node& n = V[node]; n.val = val;
rep(i,1,d) rep(j,0,sz(P)) if (n.chain != -1) C[n.chain].tree.update(n.pos, val);
jmp[i][j] = jmp[i-1][jmp[i-1][j]]; }
return jmp; CompressTree.h
} Description: Given a rooted tree and a subset S of nodes, compute the
minimal subtree that contains all the nodes by adding all (at most |S| − 1) int pard(Node& nod) {
pairwise LCA’s and compressing edges. Returns a list of (par, orig index) if (nod.par == -1) return -1;
int jmp(vector<vi>& tbl, int nod, int steps){ return V[nod.chain == -1 ? nod.par : C[nod.chain].par].d;
rep(i,0,sz(tbl)) representing a tree rooted at 0. The root points to itself.
Time: O (|S| log |S|) }
if(steps&(1<<i)) nod = tbl[i][nod];
return nod; "LCA.h" 20 lines
// query a l l ∗edges∗ between n1, n2
} vpi compressTree(LCA& lca, const vi& subset) { pair<T, int> query(int i1, int i2) {
static vi rev; rev.resize(sz(lca.dist)); T ans = LOW;
int lca(vector<vi>& tbl, vi& depth, int a, int b) { vi li = subset, &T = lca.time; while(i1 != i2) {
if (depth[a] < depth[b]) swap(a, b); auto cmp = [&](int a, int b) { return T[a] < T[b]; }; Node n1 = V[i1], n2 = V[i2];
a = jmp(tbl, a, depth[a] - depth[b]); sort(all(li), cmp); if (n1.chain != -1 && n1.chain == n2.chain) {
if (a == b) return a; int m = sz(li)-1; int lo = n1.pos, hi = n2.pos;
for (int i = sz(tbl); i--;) { rep(i,0,m) { if (lo > hi) swap(lo, hi);
int c = tbl[i][a], d = tbl[i][b]; int a = li[i], b = li[i+1]; f(ans, C[n1.chain].tree.query(lo, hi));
if (c != d) a = c, b = d; li.push_back(lca.query(a, b)); i1 = i2 = C[n1.chain].nodes[hi];
} } } else {
return tbl[0][a]; sort(all(li), cmp); if (pard(n1) < pard(n2))
} li.erase(unique(all(li)), li.end()); n1 = n2, swap(i1, i2);
rep(i,0,sz(li)) rev[li[i]] = i; if (n1.chain == -1)
vpi ret = {pii(0, li[0])};
LCA.h rep(i,0,sz(li)-1) {
f(ans, n1.val), i1 = n1.par;
Description: Data structure for computing lowest common ancestors in a else {
int a = li[i], b = li[i+1]; Chain& c = C[n1.chain];
tree (with 0 as root). C should be an adjacency list of the tree, either directed
ret.emplace_back(rev[lca.query(a, b)], b); f(ans, n1.pos ? c.tree.query(n1.pos, sz(c.nodes))
or undirected. Can also find the distance between two nodes.
} : c.tree.s[1]);
Usage: LCA lca(undirGraph);
return ret; i1 = c.par;
lca.query(firstNode, secondNode);
} }
lca.distance(firstNode, secondNode);
KTH LinkCutTree MatrixTree Point lineDistance SegmentDistance 16

}
} }
void splay() {
Geometry (8)
return make_pair(ans, i1); for (push_flip(); p; ) {
} if (p->p) p->p->push_flip();
p->push_flip(); push_flip(); 8.1 Geometric primitives
// query a l l ∗nodes∗ between n1, n2 int c1 = up(), c2 = p->up();
pair<T, int> query2(int i1, int i2) { if (c2 == -1) p->rot(c1, 2);
pair<T, int> ans = query(i1, i2); else p->p->rot(c2, c1 != c2);
f(ans.first, V[ans.second].val); } Point.h
return ans; } Description: Class to handle points in the plane. T can be e.g. double or
} Node* first() { long long. (Avoid int.) 25 lines
push_flip(); template<class T>
pii dfs(int at, int par, vector<vpi>& g, int d) { return c[0] ? c[0]->first() : (splay(), this); struct Point {
V[at].d = d; V[at].par = par; } typedef Point P;
int sum = 1, ch, nod, sz; }; T x, y;
tuple<int,int,int> mx(-1,-1,-1); explicit Point(T x=0, T y=0) : x(x), y(y) {}
trav(e, g[at]){ struct LinkCut { bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); }
if (e.first == par) continue; vector<Node> node; bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); }
tie(sz, ch) = dfs(e.first, at, g, d+1); LinkCut(int N) : node(N) {} P operator+(P p) const { return P(x+p.x, y+p.y); }
V[e.first].val = e.second; P operator-(P p) const { return P(x-p.x, y-p.y); }
sum += sz; void link(int u, int v) { // add an edge (u, v) P operator*(T d) const { return P(x*d, y*d); }
mx = max(mx, make_tuple(sz, e.first, ch)); assert(!connected(u, v)); P operator/(T d) const { return P(x/d, y/d); }
} make_root(&node[u]); T dot(P p) const { return x*p.x + y*p.y; }
tie(sz, nod, ch) = mx; node[u].pp = &node[v]; T cross(P p) const { return x*p.y - y*p.x; }
if (2*sz < sum) return pii(sum, -1); } T cross(P a, P b) const { return (a-*this).cross(b-*this); }
if (ch == -1) { ch = sz(C); C.emplace_back(); } void cut(int u, int v) { // remove an edge (u, v) T dist2() const { return x*x + y*y; }
V[nod].pos = sz(C[ch].nodes); Node *x = &node[u], *top = &node[v]; double dist() const { return sqrt((double)dist2()); }
V[nod].chain = ch; make_root(top); x->splay(); // angle to x−axis in interval [−pi , pi ]
C[ch].par = at; assert(top == (x->pp ?: x->c[0])); double angle() const { return atan2(y, x); }
C[ch].nodes.push_back(nod); if (x->pp) x->pp = 0; P unit() const { return *this/dist(); } // makes d i s t ()=1
return pii(sum, ch); else { P perp() const { return P(-y, x); } // rotates +90 degrees
} x->c[0] = top->p = 0; P normal() const { return perp().unit(); }
}; x->fix(); // returns point rotated ’a ’ radians ccw around the origin
} P rotate(double a) const {
} return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
LinkCutTree.h bool connected(int u, int v) { // are u, v in the same tree? };
Description: Represents a forest of unrooted trees. You can add and re- Node* nu = access(&node[u])->first();
move edges (as long as the result is still a forest), and check whether two return nu == access(&node[v])->first();
nodes are in the same tree. }
Time: All operations take amortized O (log N ). 90 lines void make_root(Node* u) { lineDistance.h
access(u); Description:
struct Node { // Splay tree . Root ’ s pp contains tree ’ s parent .
Node *p = 0, *pp = 0, *c[2];
u->splay(); Returns the signed distance between point p and the line con-
bool flip = 0;
if(u->c[0]) { taining points a and b. Positive value on left side and negative res
Node() { c[0] = c[1] = 0; fix(); }
u->c[0]->p = 0; on right as seen from a towards b. a==b gives nan. P is sup- e p
void fix() {
u->c[0]->flip ˆ= 1; posed to be Point<T> or Point3D<T> where T is e.g. double
if (c[0]) c[0]->p = this;
u->c[0]->pp = u; or long long. It uses products in intermediate steps so watch
if (c[1]) c[1]->p = this;
u->c[0] = 0; out for overflow if using int or long long. Using Point3D will s
// (+ update sum of subtree elements etc . i f wanted)
u->fix(); always give a non-negative distance.
} "Point.h" 4 lines
}
} template<class P>
void push_flip() {
Node* access(Node* u) { double lineDist(const P& a, const P& b, const P& p) {
if (!flip) return;
u->splay(); return (double)(b-a).cross(p-a)/(b-a).dist();
flip = 0; swap(c[0], c[1]);
while (Node* pp = u->pp) { }
if (c[0]) c[0]->flip ˆ= 1;
pp->splay(); u->pp = 0;
if (c[1]) c[1]->flip ˆ= 1;
if (pp->c[1]) {
}
e res p
pp->c[1]->p = 0; pp->c[1]->pp = pp; }
int up() { return p ? p->c[1] == this : -1; } SegmentDistance.h
pp->c[1] = u; pp->fix(); u = pp;
void rot(int i, int b) { Description:
}
int h = i ˆ b; Returns the shortest distance between point p and the line
return u;
Node *x = c[i], *y = b == 2 ? x : x->c[h], *z = b ? y : x;
} segment from point s to e. s
if ((y->p = p)) p->c[up()] = y; Usage: Point<double> a, b(2,2), p(1,1);
};
c[i] = z->c[i ˆ 1]; bool onSegment = segDist(a,b,p) < 1e-10;
if (b < 2) { "Point.h" 6 lines
x->c[h] = y->c[h ˆ 1];
MatrixTree.h typedef Point<double> P;
z->c[h ˆ 1] = b ? x : this;
Description: To count the number of spanning trees in an undirected double segDist(P& s, P& e, P& p) {
}
graph G: create an N × N matrix mat, and for each edge (a, b) ∈ G, do if (s==e) return (p-s).dist();
y->c[i ˆ 1] = b ? this : x;
mat[a][a]++, mat[b][b]++, mat[a][b]--, mat[b][a]--. Remove the auto d = (e-s).dist2(), t = min(d,max(.0,(p-s).dot(e-s)));
fix(); x->fix(); y->fix();
last row and column, and take the determinant. return ((p-s)*d-(e-s)*t).dist()/d;
if (p) p->fix();
}
swap(pp, y->pp);
KTH SegmentIntersection SegmentIntersectionQ lineIntersection sideOf onSegment linearTransformation Angle CircleIntersection 17
SegmentIntersection.h lineIntersection.h Angle.h
Description: Description: Description: A class for ordering angles (as represented by int points and
If a unique intersetion point between the line segments going If a unique intersetion point of the lines going through s1,e1 a number of rotations around the origin). Useful for rotational sweeping.
from s1 to e1 and from s2 to e2 exists r1 is set to this point and s2,e2 exists r is set to this point and 1 is returned. If no Sometimes also represents points or vectors.
and 1 is returned. If no intersection point exists 0 is returned intersection point exists 0 is returned and if infinitely many Usage: vector<Angle> v = {w[0], w[0].t360() ...}; // sorted
and if infinitely many exists 2 is returned and r1 and r2 are e1 exists -1 is returned. If s1==e1 or s2==e2 -1 is returned. The
e2 r int j = 0; rep(i,0,n) { while (v[j] < v[i].t180()) ++j; }
set to the two ends of the common line. The wrong position e2 wrong position will be returned if P is Point<int> and the in- e1 s2 // sweeps j such that (j-i) represents the number of positively
will be returned if P is Point<int> and the intersection point r1 tersection point does not have integer coordinates. Products s1 oriented triangles with vertices at 0 and i 37 lines
does not have integer coordinates. Products of three coordi- s1 s2 of three coordinates are used in intermediate steps so watch
nates are used in intermediate steps so watch out for overflow out for overflow if using int or long long. struct Angle {
if using int or long long. Use segmentIntersectionQ to get just Usage: point<double> intersection; int x, y;
a true/false answer. if (1 == LineIntersection(s1,e1,s2,e2,intersection)) int t;
Usage: Point<double> intersection, dummy; cout << "intersection point at " << intersection << endl; Angle(int x, int y, int t=0) : x(x), y(y), t(t) {}
if (segmentIntersection(s1,e1,s2,e2,intersection,dummy)==1) "Point.h" 9 lines Angle operator-(Angle b) const { return {x-b.x, y-b.y, t}; }
cout << "segments intersect at " << intersection << endl; template<class P> int quad() const {
"Point.h" 27 lines int lineIntersection(const P& s1, const P& e1, const P& s2, assert(x || y);
const P& e2, P& r) { if (y < 0) return (x >= 0) + 2;
template<class P>
if ((e1-s1).cross(e2-s2)) { // i f not p a r a l l e l l if (y > 0) return (x <= 0);
int segmentIntersection(const P& s1, const P& e1,
r = s2-(e2-s2)*(e1-s1).cross(s2-s1)/(e1-s1).cross(e2-s2); return (x <= 0) * 2;
const P& s2, const P& e2, P& r1, P& r2) {
return 1; }
if (e1==s1) {
} else Angle t90() const { return {-y, x, t + (quad() == 3)}; }
if (e2==s2) {
Angle t180() const { return {-x, -y, t + (quad() >= 2)}; }
if (e1==e2) { r1 = e1; return 1; } // a l l equal return -((e1-s1).cross(s2-s1)==0 || s2==e2);
Angle t360() const { return {x, y, t + 1}; }
else return 0; // d i f f e r e n t point segments }
};
} else return segmentIntersection(s2,e2,s1,e1,r1,r2);//swap
bool operator<(Angle a, Angle b) {
}
//segment directions and separation sideOf.h // add a . dist2 () and b . dist2 () to also compare distances
P v1 = e1-s1, v2 = e2-s2, d = s2-s1; Description: Returns where p is as seen from s towards e. 1/0/-1 ⇔ left/on return make_tuple(a.t, a.quad(), a.y * (ll)b.x) <
line/right. If the optional argument eps is given 0 is returned if p is within make_tuple(b.t, b.quad(), a.x * (ll)b.y);
auto a = v1.cross(v2), a1 = v1.cross(d), a2 = v2.cross(d);
distance eps from the line. P is supposed to be Point<T> where T is e.g. }
if (a == 0) { // i f p a r a l l e l
auto b1=s1.dot(v1), c1=e1.dot(v1), double or long long. It uses products in intermediate steps so watch out for
overflow if using int or long long. // Given two points , t h i s calculates the smallest angle between
b2=s2.dot(v1), c2=e2.dot(v1);
Usage: bool left = sideOf(p1,p2,q)==1; // them, i . e . , the angle that covers the defined l i n e segment .
if (a1 || a2 || max(b1,min(b2,c2))>min(c1,max(b2,c2)))
"Point.h" 11 lines pair<Angle, Angle> segmentAngles(Angle a, Angle b) {
return 0;
template<class P> if (b < a) swap(a, b);
r1 = min(b2,c2)<b1 ? s1 : (b2<c2 ? s2 : e2);
int sideOf(const P& s, const P& e, const P& p) { return (b < a.t180() ?
r2 = max(b2,c2)>c1 ? e1 : (b2>c2 ? s2 : e2);
auto a = (e-s).cross(p-s); make_pair(a, b) : make_pair(b, a.t360()));
return 2-(r1==r2);
return (a > 0) - (a < 0); }
}
} Angle operator+(Angle a, Angle b) { // point a + vector b
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
template<class P> Angle r(a.x + b.x, a.y + b.y, a.t);
if (0<a1 || a<-a1 || 0<a2 || a<-a2)
int sideOf(const P& s, const P& e, const P& p, double eps) { if (a.t180() < r) r.t--;
return 0;
auto a = (e-s).cross(p-s); return r.t180() < a ? r.t360() : r;
r1 = s1-v1*a2/a;
double l = (e-s).dist()*eps; }
return 1;
return (a > l) - (a < -l); Angle angleDiff(Angle a, Angle b) { // angle b − angle a
}
} int tu = b.t - a.t; a.t = b.t;
return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x, tu - (b < a)};
}
onSegment.h
Description: Returns true iff p lies on the line segment from s to e. In-
SegmentIntersectionQ.h tended for use with e.g. Point<long long> where overflow is an issue. Use 8.2 Circles
Description: Like segmentIntersection, but only returns true/false. Prod- (segDist(s,e,p)<=epsilon) instead when using Point<double>.
ucts of three coordinates are used in intermediate steps so watch out for "Point.h" 5 lines
overflow if using int or long long. template<class P> CircleIntersection.h
"Point.h" 16 lines bool onSegment(const P& s, const P& e, const P& p) { Description: Computes a pair of points at which two circles intersect. Re-
template<class P> P ds = p-s, de = p-e; turns false in case of no intersection.
bool segmentIntersectionQ(P s1, P e1, P s2, P e2) { return ds.cross(de) == 0 && ds.dot(de) <= 0; "Point.h" 14 lines

if (e1 == s1) { } typedef Point<double> P;


if (e2 == s2) return e1 == e2; bool circleIntersection(P a, P b, double r1, double r2,
swap(s1,s2); swap(e1,e2); r p1 pair<P, P>* out) {
} linearTransformation.h P delta = b - a;
Description:
P v1 = e1-s1, v2 = e2-s2, d = s2-s1; p0 res assert(delta.x || delta.y || r1 != r2);
auto a = v1.cross(v2), a1 = d.cross(v1), a2 = d.cross(v2); Apply the linear transformation (translation, rotation and q0 if (!delta.x && !delta.y) return false;
if (a == 0) { // p a r a l l e l scaling) which takes line p0-p1 to line q0-q1 to point r. q1 double r = r1 + r2, d2 = delta.dist2();
auto b1 = s1.dot(v1), c1 = e1.dot(v1), "Point.h" 6 lines double p = (d2 + r1*r1 - r2*r2) / (2.0 * d2);
b2 = s2.dot(v1), c2 = e2.dot(v1); double h2 = r1*r1 - p*p*d2;
typedef Point<double> P;
return !a1 && max(b1,min(b2,c2)) <= min(c1,max(b2,c2)); if (d2 > r*r || h2 < 0) return false;
P linearTransformation(const P& p0, const P& p1,
} P mid = a + delta*p, per = delta.perp() * sqrt(h2 / d2);
const P& q0, const P& q1, const P& r) {
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; } *out = {mid + per, mid - per};
P dp = p1-p0, dq = q1-q0, num(dp.cross(dq), dp.dot(dq));
return (0 <= a1 && a1 <= a && 0 <= a2 && a2 <= a); return true;
return q0 + P((r-p0).cross(num), (r-p0).dot(num))/dp.dist2();
} }
}
KTH circleTangents circumcircle MinimumEnclosingCircle insidePolygon PolygonArea PolygonCenter PolygonCut ConvexHull PolygonDiameter 18
circleTangents.h 8.3 Polygons vector<P> res;
Description: rep(i,0,sz(poly)) {
Returns a pair of the two points on the circle with radius r second insidePolygon.h P cur = poly[i], prev = i ? poly[i-1] : poly.back();
centered around c whos tangent lines intersect p. If p lies r Description: Returns true if p lies within the polygon described by the
bool side = s.cross(e, cur) < 0;
within the circle NaN-points are returned. P is intended to c if (side != (s.cross(e, prev) < 0)) {
points between iterators begin and end. If strict false is returned when p is res.emplace_back();
be Point<double>. The first point is the one to the right as
p first on the edge of the polygon. Answer is calculated by counting the number of lineIntersection(s, e, cur, prev, res.back());
seen from the p towards c. intersections between the polygon and a line going from p to infinity in the
Usage: typedef Point<double> P; }
positive x-direction. The algorithm uses products in intermediate steps so if (side)
pair<P,P> p = circleTangents(P(100,2),P(0,0),2); watch out for overflow. If points within epsilon from an edge should be con-
6 lines
res.push_back(cur);
"Point.h" sidered as on the edge replace the line ”if (onSegment...” with the comment }
template<class P> bellow it (this will cause overflow for int and long long). return res;
pair<P,P> circleTangents(const P &p, const P &c, double r) { Usage: typedef Point<int> pi; }
P a = p-c; vector<pi> v; v.push back(pi(4,4));
double x = r*r/a.dist2(), y = sqrt(x-x*x); v.push back(pi(1,2)); v.push back(pi(2,1));
return make_pair(c+a*x+a.perp()*y, c+a*x-a.perp()*y); bool in = insidePolygon(v.begin(),v.end(), pi(3,4), false);
} Time: O (n) ConvexHull.h
"Point.h", "onSegment.h", "SegmentDistance.h" 14 lines Description:
Returns a vector of indices of the convex hull in counter-
template<class It, class P>
circumcircle.h bool insidePolygon(It begin, It end, const P& p,
clockwise order. Points on the edge of the hull between two
Description: other points are not considered part of the hull.
The circumcirle of a triangle is the circle intersecting all B bool strict = true) { Usage: vector<P> ps, hull;
int n = 0; //number of i s e c t s with l i n e from p to ( inf , p . y)
three vertices. ccRadius returns the radius of the circle going r c for (It i = begin, j = end-1; i != end; j = i++) {
trav(i, convexHull(ps)) hull.push back(ps[i]);
C Time: O (n log n)
through points A, B and C and ccCenter returns the center // i f p i s on edge of polygon
of the same circle. A if (onSegment(*i, *j, p)) return !strict;
"Point.h" 20 lines

typedef Point<ll> P;
"Point.h" 9 lines //or : i f ( segDist (∗ i , ∗j , p) <= epsilon ) return ! s t r i c t ;
pair<vi, vi> ulHull(const vector<P>& S) {
typedef Point<double> P; //increment n i f segment intersects l i n e from p
vi Q(sz(S)), U, L;
double ccRadius(const P& A, const P& B, const P& C) { n += (max(i->y,j->y) > p.y && min(i->y,j->y) <= p.y &&
iota(all(Q), 0);
return (B-A).dist()*(C-B).dist()*(A-C).dist()/ ((*j-*i).cross(p-*i) > 0) == (i->y <= p.y));
sort(all(Q), [&S](int a, int b){ return S[a] < S[b]; });
abs((B-A).cross(C-A))/2; }
trav(it, Q) {
} return n&1; //inside i f odd number of intersections
#define ADDP(C, cmp) while (sz(C) > 1 && S[C[sz(C)-2]].cross(\
P ccCenter(const P& A, const P& B, const P& C) { }
S[it], S[C.back()]) cmp 0) C.pop_back(); C.push_back(it);
P b = C-A, c = B-A; ADDP(U, <=); ADDP(L, >=);
return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2; PolygonArea.h }
} Description: Returns twice the signed area of a polygon. Clockwise enu- return {U, L};
meration gives negative area. Watch out for overflow if using int as T! }
MinimumEnclosingCircle.h "Point.h" 6 lines
Description: Computes the minimum circle that encloses a set of points. template<class T> vi convexHull(const vector<P>& S) {
Time: expected O (n) T polygonArea2(vector<Point<T>>& v) { vi u, l; tie(u, l) = ulHull(S);
"circumcircle.h" 28 lines T a = v.back().cross(v[0]); if (sz(S) <= 1) return u;
rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]); if (S[u[0]] == S[u[1]]) return {0};
pair<double, P> mec2(vector<P>& S, P a, P b, int n) {
return a; l.insert(l.end(), u.rbegin()+1, u.rend()-1);
double hi = INFINITY, lo = -hi;
} return l;
rep(i,0,n) {
}
auto si = (b-a).cross(S[i]-a);
if (si == 0) continue; PolygonCenter.h
P m = ccCenter(a, b, S[i]); Description: Returns the center of mass for a polygon.
auto cr = (b-a).cross(m-a); "Point.h" 10 lines
PolygonDiameter.h
if (si < 0) hi = min(hi, cr); Description: Calculates the max squared distance of a set of points.
else lo = max(lo, cr); typedef Point<double> P; "ConvexHull.h" 19 lines
} Point<double> polygonCenter(vector<P>& v) { vector<pii> antipodal(const vector<P>& S, vi& U, vi& L) {
double v = (0 < lo ? lo : hi < 0 ? hi : 0); auto i = v.begin(), end = v.end(), j = end-1; vector<pii> ret;
P c = (a + b) / 2 + (b - a).perp() * v / (b - a).dist2(); Point<double> res{0,0}; double A = 0; int i = 0, j = sz(L) - 1;
return {(a - c).dist2(), c}; for (; i != end; j=i++) { while (i < sz(U) - 1 || j > 0) {
} res = res + (*i + *j) * j->cross(*i); ret.emplace_back(U[i], L[j]);
pair<double, P> mec(vector<P>& S, P a, int n) { A += j->cross(*i); if (j == 0 || (i != sz(U)-1 && (S[L[j]] - S[L[j-1]])
random_shuffle(S.begin(), S.begin() + n); } .cross(S[U[i+1]] - S[U[i]]) > 0)) ++i;
P b = S[0], c = (a + b) / 2; return res / A / 3; else --j;
double r = (a - c).dist2(); } }
rep(i,1,n) if ((S[i] - c).dist2() > r * (1 + 1e-8)) { return ret;
tie(r,c) = (n == sz(S) ? PolygonCut.h e }
mec(S, S[i], i) : mec2(S, a, S[i], i)); Description:
} Returns a vector with the vertices of a polygon with every- pii polygonDiameter(const vector<P>& S) {
return {r, c}; thing to the left of the line going from s to e cut away. vi U, L; tie(U, L) = ulHull(S);
} Usage: vector<P> p = ...; s pair<ll, pii> ans;
pair<double, P> enclosingCircle(vector<P> S) { p = polygonCut(p, P(0,0), P(1,0)); trav(x, antipodal(S, U, L))
assert(!S.empty()); auto r = mec(S, S[0], sz(S)); "Point.h", "lineIntersection.h" 15 lines ans = max(ans, {(S[x.first] - S[x.second]).dist2(), x});
return {sqrt(r.first), r.second}; return ans.second;
typedef Point<double> P;
} }
vector<P> polygonCut(const vector<P>& poly, P s, P e) {
KTH PointInsideHull LineHullIntersection ClosestPair kdTree DelaunayTriangulation 19
PointInsideHull.h hi = mid; bool on_x(const P& a, const P& b) { return a.x < b.x; }
Description: Determine whether a point t lies inside a given polygon else lo = mid; bool on_y(const P& a, const P& b) { return a.y < b.y; }
(counter-clockwise order). The polygon must be such that every point on }
the circumference is visible from the first point in the vector. It returns 0 return a[hi%N].second; struct Node {
for points outside, 1 for points on the circumference, and 2 for points inside. } P pt; // i f t h i s i s a leaf , the single point in i t
Time: O (log N ) T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; // bounds
"Point.h", "sideOf.h", "onSegment.h" 22 lines bool isign(P a, P b, int x, int y, int s) { Node *first = 0, *second = 0;
typedef Point<ll> P; return sgn(a.cross(p[x], b)) * sgn(a.cross(p[y], b)) == s;
int insideHull2(const vector<P>& H, int L, int R, const P& p) { } T distance(const P& p) { // min squared distance to a point
int len = R - L; T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x);
if (len == 2) { int bs2(int lo, int hi, P a, P b) { T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y);
int sa = sideOf(H[0], H[L], p); int L = lo; return (P(x,y) - p).dist2();
int sb = sideOf(H[L], H[L+1], p); if (hi < lo) hi += N; }
int sc = sideOf(H[L+1], H[0], p); while (hi - lo > 1) {
if (sa < 0 || sb < 0 || sc < 0) return 0; int mid = (lo + hi) / 2; Node(vector<P>&& vp) : pt(vp[0]) {
if (sb==0 || (sa==0 && L == 1) || (sc == 0 && R == sz(H))) if (isign(a, b, mid, L, -1)) hi = mid; for (P p : vp) {
return 1; else lo = mid; x0 = min(x0, p.x); x1 = max(x1, p.x);
return 2; } y0 = min(y0, p.y); y1 = max(y1, p.y);
} return lo; }
int mid = L + len / 2; } if (vp.size() > 1) {
if (sideOf(H[0], H[mid], p) >= 0) // s p l i t on x i f the box i s wider than high (not best
return insideHull2(H, mid, R, p); pii isct(P a, P b) { heuristic . . . )
return insideHull2(H, L, mid+1, p); int f = bs(a - b), j = bs(b - a); sort(all(vp), x1 - x0 >= y1 - y0 ? on_x : on_y);
} if (isign(a, b, f, j, 1)) return {-1, -1}; // divide by taking h a l f the array for each child (not
int x = bs2(f, j, a, b)%N, // best performance with many duplicates in the middle)
int insideHull(const vector<P>& hull, const P& p) { y = bs2(j, f, a, b)%N; int half = sz(vp)/2;
if (sz(hull) < 3) return onSegment(hull[0], hull.back(), p); if (a.cross(p[x], b) == 0 && first = new Node({vp.begin(), vp.begin() + half});
else return insideHull2(hull, 1, sz(hull), p); a.cross(p[x+1], b) == 0) return {x, x}; second = new Node({vp.begin() + half, vp.end()});
} if (a.cross(p[y], b) == 0 && }
a.cross(p[y+1], b) == 0) return {y, y}; }
if (a.cross(p[f], b) == 0) return {f, -1}; };
LineHullIntersection.h if (a.cross(p[j], b) == 0) return {j, -1};
Description: Line-convex polygon intersection. The polygon must be ccw return {x, y}; struct KDTree {
and have no colinear points. isct(a, b) returns a pair describing the inter- } Node* root;
section of a line with the polygon: • (−1, −1) if no collision, • (i, −1) if }; KDTree(const vector<P>& vp) : root(new Node({all(vp)})) {}
touching the corner i, • (i, i) if along side (i, i + 1), • (i, j) if crossing sides
(i, i + 1) and (j, j + 1). In the last case, if a corner i is crossed, this is treated pair<T, P> search(Node *node, const P& p) {
as happening on side (i, i + 1). The points are returned in the same order as 8.4 Misc. Point Set Problems if (!node->first) {
the line hits the polygon. // uncomment i f we should not find the point i t s e l f :
Time: O (N + Q log n) // i f (p == node−>pt ) return {INF, P() };
ClosestPair.h return make_pair((p - node->pt).dist2(), node->pt);
"Point.h" 63 lines Description: Finds the closest pair of points.
}
ll sgn(ll a) { return (a > 0) - (a < 0); } Time: O (n log n)
typedef Point<ll> P; "Point.h" 17 lines
Node *f = node->first, *s = node->second;
struct HullIntersection { typedef Point<ll> P; T bfirst = f->distance(p), bsec = s->distance(p);
int N; pair<P, P> closest(vector<P> v) { if (bfirst > bsec) swap(bsec, bfirst), swap(f, s);
vector<P> p; assert(sz(v) > 1);
vector<pair<P, int>> a; set<P> S; // search c l o s e s t side f i r s t , other side i f needed
sort(all(v), [](P a, P b) { return a.y < b.y; }); auto best = search(f, p);
HullIntersection(const vector<P>& ps) : N(sz(ps)), p(ps) { pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P()}}; if (bsec < best.first)
p.insert(p.end(), all(ps)); int j = 0; best = min(best, search(s, p));
int b = 0; trav(p, v) { return best;
rep(i,1,N) if (P{p[i].y,p[i].x} < P{p[b].y, p[b].x}) b = i; P d{1 + (ll)sqrt(ret.first), 0}; }
rep(i,0,N) { while (v[j].y <= p.y - d.x) S.erase(v[j++]);
int f = (i + b) % N; auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d); // find nearest point to a point , and i t s squared distance
a.emplace_back(p[f+1] - p[f], f); for (; lo != hi; ++lo) // ( requires an arbitrary operator< for Point)
} ret = min(ret, {(*lo - p).dist2(), {*lo, p}}); pair<T, P> nearest(const P& p) {
} S.insert(p); return search(root, p);
} }
int qd(P p) { return ret.second; };
return (p.y < 0) ? (p.x >= 0) + 2 }
: (p.x <= 0) * (1 + (p.y <= 0));
}
kdTree.h DelaunayTriangulation.h
int bs(P dir) { Description: KD-tree (2d, can be extended to 3d) Description: Computes the Delaunay triangulation of a set of points. Each
int lo = -1, hi = N; "Point.h" 63 lines circumcircle contains none of the input points. If any three points are colin-
while (hi - lo > 1) { typedef long long T; ear or any four
 are on the same circle, behavior is undefined.
int mid = (lo + hi) / 2; typedef Point<T> P; Time: O n2
if (make_pair(qd(dir), dir.y * a[mid].first.x) < const T INF = numeric_limits<T>::max(); "Point.h", "3dHull.h" 10 lines

make_pair(qd(a[mid].first), dir.x * a[mid].first.y)) template<class P, class F>


KTH PolyhedronVolume Point3D 3dHull sphericalDistance KMP 20
void delaunay(vector<P>& ps, F trifun) { Point3D.h
if (sz(ps) == 3) { int d = (ps[0].cross(ps[1], ps[2]) < 0); Description: Class to handle points in 3D space. T can be e.g. double or rep(i,4,sz(A)) {
trifun(0,1+d,2-d); } long long. 32 lines
rep(j,0,sz(FS)) {
vector<P3> p3; F f = FS[j];
trav(p, ps) p3.emplace_back(p.x, p.y, p.dist2()); template<class T> struct Point3D { if(f.q.dot(A[i]) > f.q.dot(A[f.a])) {
if (sz(ps) > 3) trav(t, hull3d(p3)) if ((p3[t.b]-p3[t.a]). typedef Point3D P; E(a,b).rem(f.c);
cross(p3[t.c]-p3[t.a]).dot(P3(0,0,1)) < 0) typedef const P& R; E(a,c).rem(f.b);
trifun(t.a, t.c, t.b); T x, y, z; E(b,c).rem(f.a);
} explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {} swap(FS[j--], FS.back());
bool operator<(R p) const { FS.pop_back();
return tie(x, y, z) < tie(p.x, p.y, p.z); } }
bool operator==(R p) const { }
return tie(x, y, z) == tie(p.x, p.y, p.z); } int nw = sz(FS);
P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); } rep(j,0,nw) {
P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); } F f = FS[j];
P operator*(T d) const { return P(x*d, y*d, z*d); } #define C(a, b, c) if (E(a,b).cnt() != 2) mf(f.a, f.b, i, f.c);
P operator/(T d) const { return P(x/d, y/d, z/d); } C(a, b, c); C(a, c, b); C(b, c, a);
T dot(R p) const { return x*p.x + y*p.y + z*p.z; } }
P cross(R p) const { }
return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); trav(it, FS) if ((A[it.b] - A[it.a]).cross(
} A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b);
T dist2() const { return x*x + y*y + z*z; } return FS;
double dist() const { return sqrt((double)dist2()); } };
//Azimuthal angle ( longitude ) to x−axis in interval [−pi , pi ]
double phi() const { return atan2(y, x); }
//Zenith angle ( l a t i t u d e ) to the z−axis in interval [0 , pi ] sphericalDistance.h
double theta() const { return atan2(sqrt(x*x+y*y),z); } Description: Returns the shortest distance on the sphere with radius ra-
P unit() const { return *this/(T)dist(); } //makes d i s t ()=1 dius between the points with azimuthal angles (longitude) f1 (φ1 ) and f2 (φ2 )
//returns unit vector normal to ∗ t h i s and p from x axis and zenith angles (latitude) t1 (θ1 ) and t2 (θ2 ) from z axis. All
P normal(P p) const { return cross(p).unit(); } angles measured in radians. The algorithm starts by converting the spheri-
//returns point rotated ’ angle ’ radians ccw around axis cal coordinates to cartesian coordinates so if that is what you have you can
P rotate(double angle, P axis) const { use only the two last rows. dx*radius is then the difference between the
double s = sin(angle), c = cos(angle); P u = axis.unit(); two points in the x direction and d*radius is the total distance between the
return u*dot(u)*(1-c) + (*this)*c - cross(u)*s; points. 8 lines
}
}; double sphericalDistance(double f1, double t1,
double f2, double t2, double radius) {
double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1);
3dHull.h double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1);
Description: Computes all faces of the 3-dimension hull of a point set. *No double dz = cos(t2) - cos(t1);
four points must be coplanar*, or else random results will be returned. All double d = sqrt(dx*dx + dy*dy + dz*dz);
faces will point
 outwards. return radius*2*asin(d/2);
Time: O n2 }
"Point3D.h" 49 lines

typedef Point3D<double> P3;


Strings (9)
8.5 3D struct PR {
void ins(int x) { (a == -1 ? a : b) = x; }
void rem(int x) { (a == x ? a : b) = -1; } KMP.h
int cnt() { return (a != -1) + (b != -1); } Description: pi[x] computes the length of the longest prefix of s that ends
int a, b; at x, other than s[0...x] itself (abacaba -> 0010123). Can be used to find all
}; occurrences of a string.
Time: O (n) 16 lines
struct F { P3 q; int a, b, c; };
vi pi(const string& s) {
vi p(sz(s));
vector<F> hull3d(const vector<P3>& A) {
rep(i,1,sz(s)) {
assert(sz(A) >= 4);
int g = p[i-1];
vector<vector<PR>> E(sz(A), vector<PR>(sz(A), {-1, -1}));
while (g && s[i] != s[g]) g = p[g-1];
#define E(x,y) E[f.x][f.y]
p[i] = g + (s[i] == s[g]);
vector<F> FS;
PolyhedronVolume.h }
auto mf = [&](int i, int j, int k, int l) {
Description: Magic formula for the volume of a polyhedron. Faces should return p;
P3 q = (A[j] - A[i]).cross((A[k] - A[i]));
point outwards. }
6 lines if (q.dot(A[l]) > q.dot(A[i]))
q = q * -1;
template<class V, class L> vi match(const string& s, const string& pat) {
F f{q, i, j, k};
double signed_poly_volume(const V& p, const L& trilist) { vi p = pi(pat + ’\0’ + s), res;
E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i);
double v = 0; rep(i,sz(p)-sz(s),sz(p))
FS.push_back(f);
trav(i, trilist) v += p[i.a].cross(p[i.b]).dot(p[i.c]); if (p[i] == sz(pat)) res.push_back(i - 2 * sz(pat));
};
return v / 6; return res;
rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4)
} }
mf(i, j, k, 6 - i - j - k);
KTH Manacher MinRotation SuffixArray SuffixTree Hashing AhoCorasick 21
Manacher.h Description: Ukkonen’s algorithm for online suffix tree construction. Each ull x; H(ull x=0) : x(x) {}
Description: For each position in a string, computes p[0][i] = half length node contains indices [l, r) into the string, and a list of child nodes. Suffixes #define OP(O,A,B) H operator O(H o) { ull r = x; asm \
of longest even palindrome around pos i, p[1][i] = longest odd (half rounded are given by traversals of this tree, joining [l, r) substrings. The root is 0 (has (A "addq %%rdx, %0\n adcq $0,%0" : "+a"(r) : B); return r; }
down). l = -1, r = 0), non-existent children are -1. To get a complete tree, append OP(+,,"d"(o.x)) OP(*,"mul %1\n", "r"(o.x) : "rdx")
Time: O (N ) 11 lines
a dummy symbol – otherwise it may contain an incomplete path (still useful H operator-(H o) { return *this + ∼o.x; }
for substring matching, though). ull get() const { return x + !∼x; }
void manacher(const string& s) { Time: O (26N ) bool operator==(H o) const { return get() == o.get(); }
int n = sz(s); 50 lines
bool operator<(H o) const { return get() < o.get(); }
vi p[2] = {vi(n+1), vi(n)}; struct SuffixTree { };
rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++) { enum { N = 200010, ALPHA = 26 }; // N ∼ 2∗maxlen+10 static const H C = (ll)1e11+3; // (order ∼ 3e9 ; random also ok)
int t = r-i+!z; int toi(char c) { return c - ’a’; }
if (i<r) p[z][i] = min(t, p[z][l+t]); string a; // v = cur node , q = cur position struct HashInterval {
int L = i-p[z][i], R = i+p[z][i]-!z; int t[N][ALPHA],l[N],r[N],p[N],s[N],v=0,q=0,m=2; vector<H> ha, pw;
while (L>=1 && R+1<n && s[L-1] == s[R+1]) HashInterval(string& str) : ha(sz(str)+1), pw(ha) {
p[z][i]++, L--, R++; void ukkadd(int i, int c) { suff: pw[0] = 1;
if (R>r) l=L, r=R; if (r[v]<=q) { rep(i,0,sz(str))
}} if (t[v][c]==-1) { t[v][c]=m; l[m]=i; ha[i+1] = ha[i] * C + str[i],
p[m++]=v; v=s[v]; q=r[v]; goto suff; } pw[i+1] = pw[i] * C;
v=t[v][c]; q=l[v]; }
MinRotation.h } H hashInterval(int a, int b) { // hash [ a , b)
Description: Finds the lexicographically smallest rotation of a string. if (q==-1 || c==toi(a[q])) q++; else { return ha[b] - ha[a] * pw[b - a];
Usage: rotate(v.begin(), v.begin()+min rotation(v), v.end()); l[m+1]=i; p[m+1]=m; l[m]=l[v]; r[m]=q; }
Time: O (N ) p[m]=p[v]; t[m][c]=m+1; t[m][toi(a[q])]=v; };
8 lines l[v]=q; p[v]=m; t[p[m]][toi(a[l[m]])]=m;
int min_rotation(string s) { v=s[p[m]]; q=l[m]; vector<H> getHashes(string& str, int length) {
int a=0, N=sz(s); s += s; while (q<r[m]) { v=t[v][toi(a[q])]; q+=r[v]-l[v]; } if (sz(str) < length) return {};
rep(b,0,N) rep(i,0,N) { if (q==r[m]) s[m]=v; else s[m]=m+2; H h = 0, pw = 1;
if (a+i == b || s[a+i] < s[b+i]) {b += max(0, i-1); break;} q=r[v]-(q-r[m]); m+=2; goto suff; rep(i,0,length)
if (s[a+i] > s[b+i]) { a = b; break; } } h = h * C + str[i], pw = pw * C;
} } vector<H> ret = {h};
return a; rep(i,length,sz(str)) {
} SuffixTree(string a) : a(a) { ret.push_back(h = h * C + str[i] - pw * str[i-length]);
fill(r,r+N,sz(a)); }
memset(s, 0, sizeof s); return ret;
SuffixArray.h memset(t, -1, sizeof t); }
Description: Builds suffix array for a string. sa[i] is the starting index fill(t[1],t[1]+ALPHA,0);
of the suffix which is i’th in the sorted suffix array. The returned vector s[0] = 1; l[0] = l[1] = -1; r[0] = r[1] = p[0] = p[1] = 0; H hashString(string& s) { H h{}; trav(c,s) h=h*C+c; return h; }
is of size n + 1, and sa[0] = n. The lcp array contains longest common rep(i,0,sz(a)) ukkadd(i, toi(a[i]));
prefixes for neighbouring strings in the suffix array: lcp[i] = lcp(sa[i], }
sa[i-1]), lcp[0] = 0. The input string must not contain any zero bytes. AhoCorasick.h
Time: O (n log n) // example : find longest common substring ( uses ALPHA = 28) Description: Aho-Corasick tree is used for multiple pattern matching. Ini-
24 lines pii best; tialize the tree with create(patterns). find(word) returns for each position
struct SuffixArray { int lcs(int node, int i1, int i2, int olen) { the index of the longest√ word that ends there, or -1 if none. findAll( , word)
vi sa, lcp; if (l[node] <= i1 && i1 < r[node]) return 1; finds all words (up to N N many if no duplicate patterns) that start at each
SuffixArray(string& s, int lim=256) { // or basic string<int> if (l[node] <= i2 && i2 < r[node]) return 2; position (shortest first). Duplicate patterns are allowed; empty patterns are
int n = sz(s) + 1, k = 0, a, b; int mask = 0, len = node ? olen + (r[node] - l[node]) : 0; not. To find the longest words that start at each position, reverse all input.
vi x(all(s)+1), y(n), ind(n), ws(max(n, lim)), rank(n); rep(c,0,ALPHA) if (t[node][c] != -1) Time: Function create is O (26N ) where N is the sum of length of patterns.
sa = lcp = y, iota(all(sa), 0); mask |= lcs(t[node][c], i1, i2, len); find is O (M ) where M is the length of the word. findAll is O (N M ). 67 lines
for (int j = 0, p = 0; p < n; j = max(1, j * 2), lim = p) { if (mask == 3)
p = j, iota(all(y), n - j); best = max(best, {len, r[node] - len}); struct AhoCorasick {
rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j; return mask; enum {alpha = 26, first = ’A’};
rep(i,0,n) ind[i] = x[y[i]]; } struct Node {
fill(all(ws), 0); static pii LCS(string s, string t) { // (nmatches i s optional )
rep(i,0,n) ws[ind[i]]++; SuffixTree st(s + (char)(’z’ + 1) + t + (char)(’z’ + 2)); int back, next[alpha], start = -1, end = -1, nmatches = 0;
rep(i,1,lim) ws[i] += ws[i - 1]; st.lcs(0, sz(s), sz(s) + 1 + sz(t), 0); Node(int v) { memset(next, v, sizeof(next)); }
for (int i = n; i--;) sa[--ws[ind[i]]] = y[i]; return st.best; };
swap(x, y), p = 1, x[sa[0]] = 0; } vector<Node> N;
rep(i,1,n) a = sa[i - 1], b = sa[i], x[b] = }; vector<int> backp;
(y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++; void insert(string& s, int j) {
} assert(!s.empty());
rep(i,1,n) rank[sa[i]] = i; Hashing.h int n = 0;
for (int i = 0, j; i < n - 1; lcp[rank[i++]] = k) Description: Various self-explanatory methods for string hashing. trav(c, s) {
44 lines int& m = N[n].next[c - first];
for (k && k--, j = sa[rank[i] - 1];
s[i + k] == s[j + k]; k++); // Arithmetic mod 2ˆ64−1. 2x slower than mod 2ˆ64 and more if (m == -1) { n = m = sz(N); N.emplace_back(-1); }
} // code , but works on e v i l t e s t data (e . g . Thue−Morse, where else n = m;
}; // ABBA. . . and BAAB. . . of length 2ˆ10 hash the same mod 2ˆ64) . }
// ”typedef u l l H;” instead i f you think t e s t data i s random, if (N[n].end == -1) N[n].start = j;
// or work mod 10ˆ9+7 i f the Birthday paradox i s not a problem . backp.push_back(N[n].end);
struct H { N[n].end = j;
SuffixTree.h typedef uint64_t ull; N[n].nmatches++;
KTH IntervalContainer IntervalCover ConstantIntervals TernarySearch Karatsuba LIS 22
} is.erase(it); 10.2 Misc. algorithms
AhoCorasick(vector<string>& pat) { }
N.emplace_back(-1); return is.insert(before, {L,R});
rep(i,0,sz(pat)) insert(pat[i], i); }
TernarySearch.h
Description: Find the smallest i in [a, b] that maximizes f (i), assuming
N[0].back = sz(N);
that f (a) < . . . < f (i) ≥ · · · ≥ f (b). To reverse which of the sides allows
N.emplace_back(0); void removeInterval(set<pii>& is, int L, int R) {
non-strict inequalities, change the < marked with (A) to <=, and reverse
if (L == R) return;
the loop at (B). To minimize f , change it to >, also at (B).
queue<int> q; auto it = addInterval(is, L, R);
Usage: int ind = ternSearch(0,n-1,[&](int i){return a[i];});
for (q.push(0); !q.empty(); q.pop()) { auto r2 = it->second;
Time: O (log(b − a)) 13 lines
int n = q.front(), prev = N[n].back; if (it->first == L) is.erase(it);
rep(i,0,alpha) { else (int&)it->second = L; template<class F>
int &ed = N[n].next[i], y = N[prev].next[i]; if (R != r2) is.emplace(R, r2); int ternSearch(int a, int b, F f) {
if (ed == -1) ed = y; } assert(a <= b);
else { while (b - a >= 5) {
N[ed].back = y; int mid = (a + b) / 2;
(N[ed].end == -1 ? N[ed].end : backp[N[ed].start]) IntervalCover.h if (f(mid) < f(mid+1)) // (A)
= N[y].end; Description: Compute indices of smallest set of intervals covering another a = mid;
N[ed].nmatches += N[y].nmatches; interval. Intervals should be [inclusive, exclusive). To support [inclusive, else
q.push(ed); inclusive], change (A) to add || R.empty(). Returns empty set on failure b = mid+1;
} (or if G is empty). }
} Time: O (N log N ) 19 lines rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B)
} return a;
template<class T>
} }
vi cover(pair<T, T> G, vector<pair<T, T>> I) {
vi find(string word) {
vi S(sz(I)), R;
int n = 0;
vi res; // l l count = 0;
iota(all(S), 0); Karatsuba.h
sort(all(S), [&](int a, int b) { return I[a] < I[b]; }); Description: Faster-than-naive convolution of two sequences: c[x] =
trav(c, word) {
a[i]b[x − i]. Uses the identity (aX + b)(cX + d) = acX 2 + bd + ((a +
P
T cur = G.first;
n = N[n].next[c - first];
int at = 0; c)(b + d) − ac −bd)X. See also FFT, under the Numerical chapter.
res.push_back(N[n].end);
// count += N[n ] . nmatches ;
while (cur < G.second) { // (A) Time: O N 1.6
pair<T, int> mx = make_pair(cur, -1);
}
while (at < sz(I) && I[S[at]].first <= cur) {
return res;
mx = max(mx, make_pair(I[S[at]].second, S[at]));
}
at++;
LIS.h
vector<vi> findAll(vector<string>& pat, string word) { Description: Compute indices for the longest increasing subsequence.
}
vi r = find(word); Time: O (N log N )
if (mx.second == -1) return {}; 17 lines
vector<vi> res(sz(word));
cur = mx.first; template<class I> vi lis(vector<I> S) {
rep(i,0,sz(word)) {
R.push_back(mx.second); vi prev(sz(S));
int ind = r[i];
} typedef pair<I, int> p;
while (ind != -1) {
return R; vector<p> res;
res[i - sz(pat[ind]) + 1].push_back(ind);
} rep(i,0,sz(S)) {
ind = backp[ind];
} p el { S[i], i };
//S[ i]+1 for non−decreasing
} ConstantIntervals.h auto it = lower_bound(all(res), p { S[i], 0 });
return res; Description: Split a monotone function on [from, to) into a minimal set of
} if (it == res.end()) res.push_back(el), it = --res.end();
half-open intervals on which it has the same value. Runs a callback g for
}; *it = el;
each such interval. prev[i] = it==res.begin() ?0:(it-1)->second;
Usage: constantIntervals(0, sz(v), [&](int x){return v[x];}, }
[&](int lo, int hi, T val){...}); int L = sz(res), cur = res.back().second;
Various (10) Time: O k log n k 19 lines vi ans(L);
template<class F, class G, class T> while (L--) ans[L] = cur, cur = prev[cur];
return ans;
10.1 Intervals void rec(int from, int to, F f, G g, int& i, T& p, T q) {
if (p == q) return; }
if (from == to) {
IntervalContainer.h g(i, to, p);
Description: Add and remove intervals from a set of disjoint intervals. i = to; p = q;
Will merge the added interval with any overlapping intervals in the set when } else {
adding. Intervals are [inclusive, exclusive). int mid = (from + to) >> 1;
Time: O (log N ) 23 lines rec(from, mid, f, g, i, p, f(mid));
rec(mid+1, to, f, g, i, p, q);
set<pii>::iterator addInterval(set<pii>& is, int L, int R) {
}
if (L == R) return is.end();
}
auto it = is.lower_bound({L, R}), before = it;
template<class F, class G>
while (it != is.end() && it->first <= R) {
void constantIntervals(int from, int to, F f, G g) {
R = max(R, it->second);
if (to <= from) return;
before = it = is.erase(it);
int i = from; auto p = f(i), q = f(to-1);
}
rec(from, to-1, f, g, i, p, q);
if (it != is.begin() && (--it)->second >= L) {
g(i, to, q);
L = min(L, it->first);
}
R = max(R, it->second);
KTH DivideAndConquerDP KnuthDP BumpAllocator SmallPtr BumpAllocatorSTL Unrolling SIMD 23
10.3 Dynamic programming • rep(b,0,K) rep(i,0,(1 << K)) Unrolling.h 5 lines
if (i & 1 << b) D[i] += D[iˆ(1 << b)]; #define F {...; ++i;}
DivideAndConquerDP.h computes all sums of subsets. int i = from;
Description: Given a[i] = minlo(i)≤k<hi(i) (f (i, k)) where the (minimal) while (i&3 && i < to) F // for alignment , i f needed
optimal k increases with i, computes a[i] for i = L..R − 1. while (i + 4 <= to) { F F F F }
Time: O ((N + (hi − lo)) log N ) 18 lines
10.5.2 Pragmas while (i < to) F
struct DP { // Modify at w i l l :
int lo(int ind) { return 0; } • #pragma GCC optimize ("Ofast") will make GCC SIMD.h
int hi(int ind) { return ind; } Description: Cheat sheet of SSE/AVX intrinsics, for doing arithmetic
ll f(int ind, int k) { return dp[ind][k]; }
auto-vectorize for loops and optimizes floating points on several numbers at once. Can provide a constant factor improvement
void store(int ind, int k, ll v) { res[ind] = pii(k, v); } better (assumes associativity and turns off denormals). of about 4, orthogonal to loop unrolling. Operations follow the pat-
tern " mm(256)? name (si(128|256)|epi(8|16|32|64)|pd|ps)". Not all
void rec(int L, int R, int LO, int HI) { are described here; grep for mm in /usr/lib/gcc/*/4.9/include/ for
if (L >= R) return;
• #pragma GCC target ("avx,avx2")can double performance more. If AVX is unsupported, try 128-bit operations, ”emmintrin.h” and
int mid = (L + R) >> 1; of vectorized code, but causes crashes on old machines. #define SSE and MMX before including it. For aligned memory use
pair<ll, int> best(LLONG_MAX, LO); mm malloc(size, 32) or int buf[N] alignas(32), but prefer loadu/s-
rep(k, max(LO,lo(mid)), min(HI,hi(mid))) toreu.
best = min(best, make_pair(f(mid, k), k));
• #pragma GCC optimize ("trapv") kills the program on 43 lines
#pragma GCC target ("avx2") // or sse4 .1
store(mid, best.second, best.first); integer overflows (but is really slow). #include "immintrin.h"
rec(L, mid, LO, best.second+1);
rec(mid+1, R, best.second, HI);
} BumpAllocator.h typedef __m256i mi;
void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); } Description: When you need to dynamically allocate many objects and #define L(x) _mm256_loadu_si256((mi*)&(x))
}; don’t care about freeing them. ”new X” otherwise has an overhead of some-
thing like 0.05us + 16 bytes per allocation. 8 lines
// High−l e v e l / s p e c i f i c methods :
// load (u)? si256 , store (u)? si256 , setzero si256 , mm malloc
KnuthDP.h // Either g l o b a l l y or in a single class : // blendv ( epi8 | ps | pd) ( z?y : x) , movemask epi8 ( h i b i t s of bytes )
Description: When doing DP on intervals: a[i][j] = mini<k<j (a[i][k] + static char buf[450 << 20]; // i32gather epi32 (addr , x , 4) : map addr [ ] over 32−b parts of x
a[k][j]) + f (i, j), where the (minimal) optimal k increases with both i void* operator new(size_t s) { // sad epu8 : sum of absolute differences of u8, outputs 4xi64
and j, one can solve intervals in increasing order of length, and search static size_t i = sizeof buf; // maddubs epi16 : dot product of unsigned i7 ’ s , outputs 16xi15
k = p[i][j] for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This is assert(s < i); // madd epi16 : dot product of signed i16 ’ s , outputs 8xi32
known as Knuth DP. Sufficient criteria for this are if f (b, c) ≤ f (a, d) and return (void*)&buf[i -= s]; // extractf128 si256 ( , i ) (256−>128) , cvtsi128 si32 (128−>lo32 )
f (a, c) + f (b, d) ≤ f (a, d) + f (b, c) for all a ≤ b ≤ c ≤ d. Consider also: } // permute2f128 si256(x , x ,1) swaps 128−b i t lanes
LineContainer(ch. Data structures), monotone queues, ternary search. void operator delete(void*) {} // shuffle epi32 (x , 3∗64+2∗16+1∗4+0) == x for each lane
Time: O N 2 // s h u f f l e e p i 8 (x , y) takes a vector instead of an imm
SmallPtr.h // Methods that work with most data types (append e . g . epi32 ) :
Description: A 32-bit pointer that points into BumpAllocator memory.
// set1 , blend ( i8?x : y) , add , adds ( sat . ) , mullo , sub , and/or ,
"BumpAllocator.h" 10 lines
10.4 Debugging tricks template<class T> struct ptr {
// andnot , abs , min, max, sign (1 ,x) , cmp( gt | eq) , unpack( lo | hi )
unsigned ind; int sumi32(mi m) { union {int v[8]; mi m;} u; u.m = m;
• signal(SIGSEGV, [](int) { _Exit(0); }); ptr(T* p = 0) : ind(p ? unsigned((char*)p - buf) : 0) { int ret = 0; rep(i,0,8) ret += u.v[i]; return ret; }
assert(ind < sizeof buf);
converts segfaults into Wrong Answers. Similarly one }
mi zero() { return _mm256_setzero_si256(); }
mi one() { return _mm256_set1_epi32(-1); }
can catch SIGABRT (assertion failures) and SIGFPE T& operator*() const { return *(T*)(buf + ind); } bool all_zero(mi m) { return _mm256_testz_si256(m, m); }
T* operator->() const { return &**this; }
(zero divisions). _GLIBCXX_DEBUG failures generate T& operator[](int a) const { return (&**this)[a]; }
bool all_one(mi m) { return _mm256_testc_si256(m, one()); }
SIGABRT (or SIGSEGV on gcc 5.4.0 apparently). explicit operator bool() const { return ind; } ll example_filteredDotProduct(int n, short* a, short* b) {
}; int i = 0; ll r = 0;
• feenableexcept(29); kills the program on NaNs mi zero = _mm256_setzero_si256(), acc = zero;
while (i + 16 <= n) {
(1), 0-divs (4), infinities (8) and denormals (16). BumpAllocatorSTL.h mi va = L(a[i]), vb = L(b[i]); i += 16;
Description: BumpAllocator for STL containers.
va = _mm256_and_si256(_mm256_cmpgt_epi16(vb, va), va);
Usage: vector<vector<int, small<int>>> ed(N); 14 lines mi vp = _mm256_madd_epi16(va, vb);
10.5 Optimization tricks char buf[450 << 20] alignas(16); acc = _mm256_add_epi64(_mm256_unpacklo_epi32(vp, zero),
size_t buf_ind = sizeof buf; _mm256_add_epi64(acc, _mm256_unpackhi_epi32(vp, zero)));
10.5.1 Bit hacks }
template<class T> struct small { union {ll v[4]; mi m;} u; u.m = acc; rep(i,0,4) r += u.v[i];
typedef T value_type; for (;i<n;++i) if (a[i] < b[i]) r += a[i]*b[i]; // <− equiv
• x & -x is the least bit in x. small() {} return r;
template<class U> small(const U&) {} }
• for (int x = m; x; ) { --x &= m; ... } T* allocate(size_t n) {
loops over all subset masks of m (except m itself). buf_ind -= n * sizeof(T);
buf_ind &= 0 - alignof(T);
return (T*)(buf + buf_ind);
• c = x&-x, r = x+c; (((rˆx) >> 2)/c) | r }
is the next number after x with the same number of void deallocate(T*, size_t) {}
};
bits set.
KTH techniques 24
Techniques (A) Computation of binomial coefficients
Pigeon-hole principle
Knuth-Morris-Pratt
Tries
Inclusion/exclusion Rolling polynomial hashes
techniques.txt 159 lines Catalan number Suffix array
Pick’s theorem Suffix tree
Recursion
Number theory Aho-Corasick
Divide and conquer
Integer parts Manacher’s algorithm
Finding interesting points in N log N
Divisibility Letter position lists
Algorithm analysis
Euclidean algorithm Combinatorial search
Master theorem
Modular arithmetic Meet in the middle
Amortized time complexity
Greedy algorithm * Modular multiplication Brute-force with pruning
Scheduling * Modular inverses Best-first (A*)
Max contiguous subvector sum * Modular exponentiation by squaring Bidirectional search
Chinese remainder theorem Iterative deepening DFS / A*
Invariants
Fermat’s little theorem Data structures
Huffman encoding
Euler’s theorem LCA (2ˆk-jumps in trees in general)
Graph theory
Phi function Pull/push-technique on trees
Dynamic graphs (extra book-keeping)
Frobenius number Heavy-light decomposition
Breadth first search
Quadratic reciprocity Centroid decomposition
Depth first search
Pollard-Rho Lazy propagation
* Normal trees / DFS trees Miller-Rabin Self-balancing trees
Dijkstra’s algorithm
Hensel lifting Convex hull trick (wcipeg.com/wiki/Convex_hull_trick)
MST: Prim’s algorithm
Vieta root jumping Monotone queues / monotone stacks / sliding queues
Bellman-Ford
Game theory Sliding queue using 2 stacks
Konig’s theorem and vertex cover
Combinatorial games Persistent segment tree
Min-cost max flow
Game trees
Lovasz toggle
Mini-max
Matrix tree theorem
Nim
Maximal matching, general graphs
Games on graphs
Hopcroft-Karp
Games on graphs with loops
Hall’s marriage theorem
Grundy numbers
Graphical sequences
Bipartite games without repetition
Floyd-Warshall
General games without repetition
Euler cycles
Alpha-beta pruning
Flow networks
Probability theory
* Augmenting paths Optimization
* Edmonds-Karp Binary search
Bipartite matching
Ternary search
Min. path cover
Unimodality and convex functions
Topological sorting
Binary search on derivative
Strongly connected components
Numerical methods
2-SAT
Numeric integration
Cut vertices, cut-edges and biconnected components
Newton’s method
Edge coloring
Root-finding with binary/ternary search
* Trees Golden section search
Vertex coloring
Matrices
* Bipartite graphs (=> trees) Gaussian elimination
* 3ˆn (special case of set cover) Exponentiation by squaring
Diameter and centroid
Sorting
K’th shortest path
Radix sort
Shortest cycle
Geometry
Dynamic programming
Coordinates and vectors
Knapsack
Coin change * Cross product
Longest common subsequence * Scalar product
Convex hull
Longest increasing subsequence
Polygon cut
Number of paths in a dag
Closest pair
Shortest path in a dag
Coordinate-compression
Dynprog over intervals
Quadtrees
Dynprog over subsets
KD-trees
Dynprog over probabilities
All segment-segment intersection
Dynprog over trees
Sweeping
3ˆn set cover
Discretization (convert to events and sweep)
Divide and conquer
Angle sweeping
Knuth optimization
Line sweeping
Convex hull optimizations
Discrete second derivatives
RMQ (sparse table a.k.a 2ˆk-jumps)
Strings
Bitonic cycle
Longest common substring
Log partitioning (loop over most restricted)
Palindrome subsequences
Combinatorics

You might also like