Vous êtes sur la page 1sur 25

KTH Royal Institute of Technology

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

2019-05-21
1 Contest 1 troubleshoot.txt 52 lines

Pre-submit: ed − bf
ax + by = e x=
2 Mathematics 1 Write a few simple test cases, if sample is not enough. ad − bc
Are time limits close? If so, generate max cases. ⇒
Is the memory usage fine? cx + dy = f af − ec
3 Data structures 3 Could anything overflow? y=
Make sure to submit the right file.
ad − bc
4 Numerical 5 Wrong answer:
Print your solution! Print debug output, as well.
In general, given an equation Ax = b, the solution to a
5 Number theory 8 Are you clearing all datastructures between test cases? variable xi is given by
Can your algorithm handle the whole range of input?
Read the full problem statement again.
6 Combinatorial 10 Do you handle all corner cases correctly? det A0i
Have you understood the problem correctly? xi =
Any uninitialized variables?
det A
7 Graph 11 Any overflows?
Confusing N and M, i and j, etc.? where A0i is A with the i’th column replaced by b.
Are you sure your algorithm works?
8 Geometry 17 What special cases have you not thought of?
Are you sure the STL functions you use work as you think? 2.2 Recurrences
9 Strings 20 Add some assertions, maybe resubmit.
Create some testcases to run your algorithm on.
Go through the algorithm for a simple case. If an = c1 an−1 + · · · + ck an−k , and r1 , . . . , rk are distinct
10 Various 22 Go through this list again. roots of xk + c1 xk−1 + · · · + ck , there are d1 , . . . , dk s.t.
Explain your algorithm to a team mate.
Ask the team mate to look at your code.
Contest (1) Go for a small walk, e.g. to the toilet.
Is your output format correct? (including whitespace)
an = d1 r1n + · · · + dk rkn .
Rewrite your solution from the start or let a team mate do it.
template.cpp 15 lines Non-distinct roots r become polynomial factors, e.g.
Runtime error:
#include <bits/stdc++.h>
Have you tested all corner cases locally? an = (d1 n + d2 )rn .
using namespace std;
Any uninitialized variables?
#define rep(i, a, b) for(int i = a; i < (b); ++i) Are you reading or writing outside the range of any vector?
#define trav(a, x) for(auto& a : x) Any assertions that might fail? 2.3 Trigonometry
#define all(x) begin(x), end(x) Any possible division by 0? (mod 0 for example)
#define sz(x) (int)(x).size() Any possible infinite recursion?
typedef long long ll; Invalidated pointers or iterators?
typedef pair<int, int> pii; Are you using too much memory? sin(v + w) = sin v cos w + cos v sin w
typedef vector<int> vi; Debug with resubmits (e.g. remapped signals, see Various).
cos(v + w) = cos v cos w − sin v sin w
int main() { Time limit exceeded:
cin.sync_with_stdio(0); cin.tie(0); Do you have any possible infinite loops?
cin.exceptions(cin.failbit); What is the complexity of your algorithm?
} Are you copying a lot of unnecessary data? (References)
How big is the input and output? (consider scanf)
Avoid vector, map. (use arrays/unordered_map) tan v + tan w
.bashrc What do your team mates think about your algorithm? tan(v + w) =
3 lines 1 − tan v tan w
alias c=’g++ -Wall -Wconversion -Wfatal-errors -g -std=c++14 \ Memory limit exceeded: v+w v−w
-fsanitize=undefined,address’ What is the max amount of memory your algorithm should need? sin v + sin w = 2 sin cos
xmodmap -e ’clear lock’ -e ’keycode 66=less greater’ #caps = <> Are you clearing all datastructures between test cases? 2 2
v+w v−w
.vimrc cos v + cos w = 2 cos cos
6 lines 2 2
set cin aw ai is ts=4 sw=4 tm=50 nu noeb bg=dark ru cul Mathematics (2)
sy on | im jk <esc> | im kj <esc> | no ; : (V + W ) tan(v − w)/2 = (V − W ) tan(v + w)/2
" Select region and then type :Hash to hash your selection.
" Useful for verifying that there aren’t mistypes. 2.1 Equations
ca Hash w !cpp -dD -P -fpreprocessed \| tr -d ’[:space:]’ \ where V, W are lengths of sides opposite angles v, w.
\| md5sum \| cut -c-6 √
−b ± b2 − 4ac a cos x + b sin x = r cos(x − φ)
hash.sh ax2 + bx + c = 0 ⇒ x =
3 lines 2a a sin x + b cos x = r sin(x + φ)
# Hashes a file, ignoring all whitespace and comments. Use for
# verifying that code was correctly typed.
cpp -dD -P -fpreprocessed | tr -d ’[:space:]’| md5sum |cut -c-6

The extremum is given by x = −b/2a. where r = a2 + b2 , φ = atan2(b, a).
KTH template .bashrc .vimrc hash troubleshoot 2
2.4 Geometry 2.5 Derivatives/Integrals 2.8 Probability theory
2.4.1 Triangles Let X be a discrete random variable with probability pX (x)
d 1 d 1 of assuming the valuePx. It will then have an expected value
arcsin x = √ arccos x = − √
Side lengths: a, b, c dx 1 − x2 dx 1 − x2 (mean) µ = E(X) = x xpX (x) and
a+b+c P variance
Semiperimeter: p = d d 1 σ 2 = V (X) = E(X 2 ) − (E(X))2 = x (x − E(X))2 pX (x)
2 tan x = 1 + tan2 x arctan x = where σ is the standard deviation. If X is instead
p dx dx 1 + x2
Area: A = p(p − a)(p − b)(p − c) continuous it will have a probability density function fX (x)
ln | cos ax| sin ax − ax cos ax
Z Z
abc tan ax = − x sin ax = and the sums above will instead be integrals with pX (x)
Circumradius: R = a a2
4A √ replaced by fX (x).
A eax
Z Z
2 π
Inradius: r = e−x = erf(x) xeax dx = 2 (ax − 1)
p 2 a Expectation is linear:
Length of median (divides
√ triangle into two equal-area
triangles): ma = 21 2b2 + 2c2 − a2 E(aX + bY ) = aE(X) + bE(Y )
Integration by parts:
Length
v of "bisector (divides angles in two): For independent X and Y ,
2 # Z b Z b
V (aX + bY ) = a2 V (X) + b2 V (Y ).
u 
u a f (x)g(x)dx = [F (x)g(x)]ba − F (x)g 0 (x)dx
sa = tbc 1 −
b+c a a
2.8.1 Discrete distributions
sin α sin β sin γ 1
Law of sines: = = = 2.6 Sums
a b c 2R Binomial distribution
Law of cosines: a2 = b2 + c2 − 2bc cos α c b+1
−c a
α+β ca + ca+1 + · · · + cb = , c 6= 1 The number of successes in n independent yes/no
a+b tan c−1
Law of tangents: = 2 experiments, each which yields success with probability p is
a−b α−β Bin(n, p), n = 1, 2, . . . , 0 ≤ p ≤ 1.
tan n(n + 1)
2 1 + 2 + 3 + ··· + n =  
2 n k
2.4.2 Quadrilaterals p(k) = p (1 − p)n−k
n(2n + 1)(n + 1) k
12 + 22 + 32 + · · · + n2 =
With side lengths a, b, c, d, diagonals e, f , diagonals angle θ, 6 µ = np, σ 2 = np(1 − p)
2 2
area A and magic flux F = b2 + d2 − a2 − c2 : n (n + 1)
13 + 23 + 33 + · · · + n3 = Bin(n, p) is approximately Po(np) for small p.
4
p 4 4 4 4 n(n + 1)(2n + 1)(3n2 + 3n − 1) First success distribution
4A = 2ef · sin θ = F tan θ = 4e2 f 2 − F 2 1 + 2 + 3 + ··· + n =
30
The number of trials needed to get the first success in
For cyclic quadrilateralspthe sum of opposite angles is 180◦ , independent yes/no experiments, each wich yields success
ef = ac + bd, and A = (p − a)(p − b)(p − c)(p − d). with probability p is Fs(p), 0 ≤ p ≤ 1.
2.7 Series
2.4.3 Spherical coordinates p(k) = p(1 − p)k−1 , k = 1, 2, . . .
z x x2 x3
e =1+x+ + + . . . , (−∞ < x < ∞) 1 2 1−p
2! 3! µ= ,σ =
r x2 x3 x4
p p2
y ln(1 + x) = x − + − + . . . , (−1 < x ≤ 1)
2 3 4 Poisson distribution
x √ x x 2
2x 3
5x 4
1+x=1+ − + − + . . . , (−1 ≤ x ≤ 1) The number of events occurring in a fixed period of time t if
2 8 32 128 these events occur with a known average rate κ and
x3 x5 x7 independently of the time since the last event is
sin x = x − + − + . . . , (−∞ < x < ∞)
Po(λ), λ = tκ.
p
x = r sin θ cos φ r = xp 2 + y2 + z2 3! 5! 7!
y = r sin θ sin φ θ = acos(z/ x2 + y 2 + z 2 ) x2 x4 x6 λk
z = r cos θ φ = atan2(y, x) cos x = 1 − + − + . . . , (−∞ < x < ∞) p(k) = e−λ , k = 0, 1, 2, . . .
2! 4! 6! k!
KTH OrderStatisticTree HashMap SegmentTree LazySegmentTree 3
2
µ = λ, σ = λ π is a stationary distribution if π = πP. If the Markov chain SegmentTree.h
Description: Zero-indexed max-tree. Bounds are inclusive to the left and
is irreducible (it is possible to get to any state from any exclusive to the right. Can be changed by modifying T, f and unit.
1
2.8.2 Continuous distributions state), then πi = E(Ti ) where E(Ti ) is the expected time Time: O (log N ) 0f4bdb, 19 lines

between two visits in state i. πj /πi is the expected number struct Tree {
Uniform distribution typedef int T;
of visits in state j between two visits in state i. static constexpr T unit = INT_MIN;
T f(T a, T b) { return max(a, b); } // (any associative fn )
If the probability density function is constant between a and For a connected, undirected and non-bipartite graph, where vector<T> s; int n;
b and 0 elsewhere it is U(a, b), a < b. the transition probability is uniform among all neighbors, πi Tree(int n = 0, T def = unit) : s(2*n, def), n(n) {}
void update(int pos, T val) {
 1 is proportional to node i’s degree. for (s[pos += n] = val; pos /= 2;)
b−a a<x<b s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
f (x) = }
0 otherwise A Markov chain is ergodic if the asymptotic distribution is T query(int b, int e) { // query [ b , e)
independent of the initial distribution. A finite Markov T ra = unit, rb = unit;
for (b += n, e += n; b < e; b /= 2, e /= 2) {
a+b 2 (b − a)2 chain is ergodic iff it is irreducible and aperiodic (i.e., the if (b % 2) ra = f(ra, s[b++]);
µ= ,σ =
2 12 gcd of cycle lengths is 1). limk→∞ Pk = 1π. if (e % 2) rb = f(s[--e], rb);
}
return f(ra, rb);
Exponential distribution A Markov chain is an A-chain if the states can be }
partitioned into two sets A and G, such that all states in A };
The time between events in a Poisson process is are absorbing (pii = 1), and all states in G leads to an
Exp(λ), λ > 0. absorbing state in A. The probability for absorption
P in state LazySegmentTree.h
Description: Segment tree with ability to add or set values of large intervals,
i ∈ A, when the initial state is j, is aij = pij + k∈G aik pkj . and compute max of intervals. Can be changed to other things. Use with a
λe−λx x ≥ 0 time until absorption, when the initial state is bump allocator for better performance, and SmallPtr or implicit indices to

The expectedP
f (x) = save memory.
0 x<0 i, is ti = 1 + k∈G pki tk . Usage: Node* tr = new Node(v, 0, sz(v));
Time: O (log N ).
"../various/BumpAllocator.h" 34ecf5, 50 lines
1 1 Data structures (3)
µ = , σ2 = 2 const int inf = 1e9;
λ λ struct Node {
Node *l = 0, *r = 0;
OrderStatisticTree.h int lo, hi, mset = inf, madd = 0, val = -inf;
Normal distribution Description: A set (not multiset!) with support for finding the n’th ele-
Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of −in f
ment, and finding the index of an element. To get a map, change null type.
Node(vi& v, int lo, int hi) : lo(lo), hi(hi) {
Time: O (log N ) 782797, 16 lines if (lo + 1 < hi) {
Most real random values with mean µ and variance σ 2 are #include <bits/extc++.h> int mid = lo + (hi - lo)/2;
well described by N (µ, σ 2 ), σ > 0. using namespace __gnu_pbds; l = new Node(v, lo, mid); r = new Node(v, mid, hi);
val = max(l->val, r->val);
template<class T> }
1 (x−µ)2
f (x) = √ e− 2σ 2 using Tree = tree<T, null_type, less<T>, rb_tree_tag,
tree_order_statistics_node_update>; }
else val = v[lo];
2πσ 2 int query(int L, int R) {
void example() { if (R <= lo || hi <= L) return -inf;
If X1 ∼ N (µ1 , σ12 ) and X2 ∼ N (µ2 , σ22 ) then Tree<int> t, t2; t.insert(8); if (L <= lo && hi <= R) return val;
auto it = t.insert(10).first; push();
assert(it == t.lower_bound(9)); return max(l->query(L, R), r->query(L, R));
aX1 + bX2 + c ∼ N (µ1 + µ2 + c, a2 σ12 + b2 σ22 ) assert(t.order_of_key(10) == 1); }
assert(t.order_of_key(11) == 2); void set(int L, int R, int x) {
assert(*t.find_by_order(0) == 8); if (R <= lo || hi <= L) return;
t.join(t2); // assuming T < T2 or T > T2, merge t2 into t if (L <= lo && hi <= R) mset = val = x, madd = 0;
2.9 Markov chains } else {
push(), l->set(L, R, x), r->set(L, R, x);
A Markov chain is a discrete random process with the HashMap.h
val = max(l->val, r->val);
}
property that the next state depends only on the current Description: Hash map with the same API as unordered map, but ∼3x }
state. Let X1 , X2 , . . . be a sequence of random variables faster. Initial capacity must be a power of 2 (if provided). 1443bc, 7 lines void add(int L, int R, int x) {
if (R <= lo || hi <= L) return;
generated by the Markov process. Then there is a transition #include <bits/extc++.h>
if (L <= lo && hi <= R) {
// To use most b i t s rather than j u s t the lowest ones :
matrix P = (pij ), with pij = Pr(Xn = i|Xn−1 = j), and struct chash {
if (mset != inf) mset += x;
else madd += x;
p(n) = Pn p(0) is the probability distribution for Xn (i.e., const uint64_t C = ll(2e18 * M_PI) + 71; // large odd number
val += x;
(n) ll operator()(ll x) const { return __builtin_bswap64(x*C); }
pi = Pr(Xn = i)), where p(0) is the initial };
}
else {
__gnu_pbds::gp_hash_table<ll,int,chash> h({},{},{},{},{1<<16});
distribution. push(), l->add(L, R, x), r->add(L, R, x);
KTH UnionFind SubMatrix Matrix LineContainer Treap FenwickTree 4
val = max(l->val, r->val); return a; void Node::recalc() { c = cnt(l) + cnt(r) + 1; }
} }
} vector<T> operator*(const vector<T>& vec) const { template<class F> void each(Node* n, F f) {
void push() { vector<T> ret(N); if (n) { each(n->l, f); f(n->val); each(n->r, f); }
if (!l) { rep(i,0,N) rep(j,0,N) ret[i] += d[i][j] * vec[j]; }
int mid = lo + (hi - lo)/2; return ret;
l = new Node(lo, mid); r = new Node(mid, hi); } pair<Node*, Node*> split(Node* n, int k) {
} M operatorˆ(ll p) const { if (!n) return {};
if (mset != inf) assert(p >= 0); if (cnt(n->l) >= k) { // ”n−>val >= v” for lower bound(v)
l->set(lo,hi,mset), r->set(lo,hi,mset), mset = inf; M a, b(*this); auto pa = split(n->l, k);
else if (madd) rep(i,0,N) a.d[i][i] = 1; n->l = pa.second;
l->add(lo,hi,madd), r->add(lo,hi,madd), madd = 0; while (p) { n->recalc();
} if (p&1) a = a*b; return {pa.first, n};
}; b = b*b; } else {
p >>= 1; auto pa = split(n->r, k - cnt(n->l) - 1);
} n->r = pa.first;
UnionFind.h return a; n->recalc();
Description: Disjoint-set data structure.
} return {n, pa.second};
Time: O (α(N )) b5bfc3, 14 lines }; }
struct UF { }
vi e;
UF(int n) : e(n, -1) {}
LineContainer.h Node* merge(Node* l, Node* r) {
Description: Container where you can add lines of the form kx+m, and if (!l) return r;
bool same_set(int a, int b) { return find(a) == find(b); }
query maximum values at points x. Useful for dynamic programming. if (!r) return l;
int size(int x) { return -e[find(x)]; }
Time: O (log N ) 95e223, 30 lines if (l->y > r->y) {
int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
bool join(int a, int b) { struct Line { l->r = merge(l->r, r);
a = find(a), b = find(b); mutable ll k, m, p; l->recalc();
if (a == b) return false; bool operator<(const Line& o) const { return k < o.k; } return l;
if (e[a] > e[b]) swap(a, b); bool operator<(ll x) const { return p < x; } } else {
e[a] += e[b]; e[b] = a; }; r->l = merge(l, r->l);
return true; r->recalc();
} struct LineContainer : multiset<Line, less<>> { return r;
}; // ( for doubles , use i n f = 1/.0 , div (a , b) = a/b) }
const ll inf = LLONG_MAX; }
ll div(ll a, ll b) { // floored division
SubMatrix.h return a / b - ((a ˆ b) < 0 && a % b); } Node* ins(Node* t, Node* n, int pos) {
Description: Calculate submatrix sums quickly, given upper-left and lower- auto pa = split(t, pos);
bool isect(iterator x, iterator y) {
right corners (half-open). return merge(merge(pa.first, n), pa.second);
if (y == end()) { x->p = inf; return false; }
Usage: SubMatrix<int> m(matrix); }
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
m.sum(0, 0, 2, 2); // top left 4 elements
else x->p = div(y->m - x->m, x->k - y->k);
Time: O N 2 + Q

c59ada, 13 lines 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) { FenwickTree.h
assert(!empty()); Description: Computes partial sums a[0] + a[1] + ... + a[pos - 1], and
T sum(int u, int l, int d, int r) {
auto l = *lower_bound(x); updates single elements a[i], taking the difference between the old and new
return p[d][r] - p[d][l] - p[u][r] + p[u][l];
return l.k * x + l.m; value.
}
} Time: Both operations are O (log N ).
}; e62fac, 22 lines
}; struct FT {
Matrix.h vector<ll> s;
Description: Basic operations on square matrices. Treap.h FT(int n) : s(n) {}
Usage: Matrix<int, 3> A; 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. for (; pos < sz(s); pos |= pos + 1) s[pos] += dif;
vector<int> vec = {1,2,3}; Time: O (log N ) }
9556fc, 55 lines ll query(int pos) { // sum of values in [0 , pos)
vec = (AˆN) * vec; c43c7d, 26 lines struct Node { ll res = 0;
template<class T, int N> struct Matrix { Node *l = 0, *r = 0; for (; pos > 0; pos &= pos - 1) res += s[pos-1];
typedef Matrix M; int val, y, c = 1; return res;
array<array<T, N>, N> d{}; Node(int val) : val(val), y(rand()) {} }
M operator*(const M& m) const { void recalc(); int lower_bound(ll sum) {// min pos s t sum of [0 , pos ] >= sum
M a; }; // Returns n i f no sum i s >= sum, or −1 i f empty sum i s .
rep(i,0,N) rep(j,0,N) if (sum <= 0) return -1;
rep(k,0,N) a.d[i][j] += d[i][k]*m.d[k][j]; int cnt(Node* n) { return n ? n->c : 0; } int pos = 0;
KTH FenwickTree2d RMQ GoldenSectionSearch Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence 5
for (int pw = 1 << 25; pw; pw >>= 1) { GoldenSectionSearch.h ret.push_back((l + h) / 2);
if (pos + pw <= sz(s) && s[pos + pw-1] < sum) Description: Finds the argument minimizing the function f in the inter- }
pos += pw, sum -= s[pos-1]; val [a, b] assuming f is unimodal on the interval, i.e. has only one local }
} minimum. The maximum error in the result is eps. Works equally well for return ret;
return pos; 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; }
double xmin = gss(-1000,1000,func);
PolyInterpolate.h
Description: Given n points (x[i], y[i]), computes an n-1-degree polynomial
Time: O (log((b − a)/)) 31d45b, 14 lines
p that passes through them: p(x) = a[0] ∗ x0 + ... + a[n − 1] ∗ xn−1 . For
FenwickTree2d.h double gss(double a, double b, double (*f)(double)) { numerical precision, pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1.
Description: Computes sums a[i,j] for all i<I, j<J, and increases single ele- double r = (sqrt(5)-1)/2, eps = 1e-7; Time: O n2

ments a[i,j]. Requires that the elements to be updated are known in advance 08bf48, 13 lines
double x1 = b - r*(b-a), x2 = a + r*(b-a);
(call fakeUpdate() before init()). double f1 = f(x1), f2 = f(x2); typedef vector<double> vd;
Time: O log2 N . (Use persistent segment trees for O (log N ).) while (b-a > eps) vd interpolate(vd x, vd y, int n) {
"FenwickTree.h" b28c27, 22 lines
if (f1 < f2) { //change to > to find maximum vd res(n), temp(n);
struct FT2 { b = x2; x2 = x1; f2 = f1; rep(k,0,n-1) rep(i,k+1,n)
vector<vi> ys; vector<FT> ft; x1 = b - r*(b-a); f1 = f(x1); y[i] = (y[i] - y[k]) / (x[i] - x[k]);
FT2(int limx) : ys(limx) {} } else { double last = 0; temp[0] = 1;
void fakeUpdate(int x, int y) { a = x1; x1 = x2; f1 = f2; rep(k,0,n) rep(i,0,n) {
for (; x < sz(ys); x |= x + 1) ys[x].push_back(y); x2 = a + r*(b-a); f2 = f(x2); res[i] += y[k] * temp[i];
} } swap(last, temp[i]);
void init() { return a; temp[i] -= last * x[k];
trav(v, ys) sort(all(v)), ft.emplace_back(sz(v)); } }
} return res;
int ind(int x, int y) { }
return (int)(lower_bound(all(ys[x]), y) - ys[x].begin()); } Polynomial.h c9b7b0, 17 lines
void update(int x, int y, ll dif) { BerlekampMassey.h
for (; x < sz(ys); x |= x + 1) struct Poly {
vector<double> a; Description: Recovers any n-order linear recurrence relation from the first
ft[x].update(ind(x, y), dif); 2n terms of the recurrence. Useful for guessing linear recurrences after brute-
} double operator()(double x) const {
double val = 0; forcing the first terms. Should work on any field, but numerical stability for
ll query(int x, int y) { floats is not guaranteed. Output will have size ≤ n.
ll sum = 0; for(int i = sz(a); i--;) (val *= x) += a[i];
return val; Usage: BerlekampMassey({0, 1, 1, 3, 5, 11}) // {1, 2}
for (; x; x &= x - 1) "../number-theory/ModPow.h" 40387d, 20 lines
sum += ft[x-1].query(ind(x-1, y)); }
return sum; void diff() { vector<ll> BerlekampMassey(vector<ll> s) {
} 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;
void divroot(double x0) {
double b = a.back(), c; a.back() = 0; ll b = 1;
RMQ.h for(int i=sz(a)-1; i--;) c = a[i], a[i] = a[i+1]*x0+b, b=c; rep(i,0,n) { ++m;
Description: Range Minimum Queries on an array. Returns min(V[a], V[a a.pop_back(); ll d = s[i] % mod;
+ 1], ... V[b - 1]) in constant time. } rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
Usage: RMQ rmq(values); }; if (!d) continue;
rmq.query(inclusive, exclusive); T = C; ll coef = d * modpow(b, mod-2) % mod;
Time: O (|V | log |V | + Q) 1f8996, 19 lines 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" 2cf190, 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 < N) 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(); LinearRecurrence.h
jmp[i][min(N - 1, j + (1 << i))]); auto dr = poly_roots(der, xmin, xmax); Description: Generates the k’th term of an n-order linear recurrence
} dr.push_back(xmin-1); P
S[i] = j S[i − j − 1]tr[j], given S[0 . . . n − 1] and tr[0 . . . n − 1]. Faster than
dr.push_back(xmax+1); matrix multiplication. Useful together with Berlekamp–Massey.
T query(int a, int b) { sort(all(dr)); Usage: linearRec({0, 1}, {1, 1}, k) // k’th Fibonacci number
assert(a < b); // or return i n f i f a == b rep(i,0,sz(dr)-1) { Time: O n2 log k

int dep = 31 - __builtin_clz(b - a); double l = dr[i], h = dr[i+1]; da800e, 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) {
else h = m; Poly res(n * 2 + 1);
Numerical (4) } rep(i,0,n+1) rep(j,0,n+1)
KTH HillClimbing Integrate IntegrateAdaptive Determinant IntDeterminant Simplex SolveLinear 6
res[i + j] = (res[i + j] + a[i] * b[j]) % mod; return T + (T - S) / 15;
for (int i = 2 * n; i > n; --i) rep(j,0,n) return rec(f, a, c, eps / 2, S1) + rec(f, c, b, eps / 2, S2); const T eps = 1e-8, inf = 1/.0;
res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod; } #define MP make_pair
res.resize(n + 1); template<class F> #define ltj(X) if(s == -1 || MP(X[j],N[j]) < MP(X[s],N[s])) s=j
return res; d quad(d a, d b, F f, d eps = 1e-8) {
}; return rec(f, a, b, eps, S(a, b)); struct LPSolver {
} int m, n;
Poly pol(n + 1), e(pol); vi N, B;
pol[0] = e[1] = 1; vvd D;
Determinant.h
for (++k; k; k /= 2) { Description: Calculates determinant of a matrix. Destroys the matrix. LPSolver(const vvd& A, const vd& b, const vd& c) :
if (k % 2) pol = combine(pol, e); Time: O N 3 bd5cec, 15 lines m(sz(b)), n(sz(c)), N(n+1), B(m), D(m+2, vd(n+2)) {
e = combine(e, e); double det(vector<vector<double>>& a) { rep(i,0,m) rep(j,0,n) D[i][j] = A[i][j];
} int n = sz(a); double res = 1; rep(i,0,m) { B[i] = n+i; D[i][n] = -1; D[i][n+1] = b[i];}
rep(i,0,n) { rep(j,0,n) { N[j] = j; D[m][j] = -c[j]; }
ll res = 0; int b = i; N[n] = -1; D[m+1][n] = 1;
rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod; rep(j,i+1,n) if (fabs(a[j][i]) > fabs(a[b][i])) b = j; }
return res; if (i != b) swap(a[i], a[b]), res *= -1;
} res *= a[i][i]; void pivot(int r, int s) {
if (res == 0) return 0; T *a = D[r].data(), inv = 1 / a[s];
rep(i,0,m+2) if (i != r && abs(D[i][s]) > eps) {
HillClimbing.h rep(j,i+1,n) {
T *b = D[i].data(), inv2 = b[s] * inv;
Description: Poor man’s optimization for unimodal functions.f40e55, double v = a[j][i] / a[i][i];
16 lines
if (v != 0) rep(k,i+1,n) a[j][k] -= v * a[i][k]; rep(j,0,n+2) b[j] -= a[j] * inv2;
typedef array<double, 2> P; } b[s] = a[s] * inv2;
} }
double func(P p); return res; rep(j,0,n+2) if (j != s) D[r][j] *= inv;
} rep(i,0,m+2) if (i != r) D[i][s] *= -inv;
pair<double, P> hillClimb(P start) { D[r][s] = inv;
pair<double, P> cur(func(start), start); swap(B[r], N[s]);
for (double jmp = 1e9; jmp > 1e-20; jmp /= 2) { IntDeterminant.h }
rep(j,0,100) rep(dx,-1,2) rep(dy,-1,2) { Description: Calculates determinant using modular arithmetics. Modulos
P p = cur.second; can also be removed to get a pure-integer version. bool simplex(int phase) {
Time: O N 3 int x = m + phase - 1;

p[0] += dx*jmp;
3313dc, 18 lines
p[1] += dy*jmp; for (;;) {
cur = min(cur, make_pair(func(p), p)); const ll mod = 12345; int s = -1;
} ll det(vector<vector<ll>>& a) { rep(j,0,n+1) if (N[j] != -phase) ltj(D[x]);
} int n = sz(a); ll ans = 1; if (D[x][s] >= -eps) return true;
return cur; rep(i,0,n) { int r = -1;
} rep(j,i+1,n) { rep(i,0,m) {
while (a[j][i] != 0) { // gcd step if (D[i][s] <= eps) continue;
ll t = a[i][i] / a[j][i]; if (r == -1 || MP(D[i][n+1] / D[i][s], B[i])
Integrate.h if (t) rep(k,i,n) < MP(D[r][n+1] / D[r][s], B[r])) r = i;
Description: Simple integration of a function over an interval using Simp- a[i][k] = (a[i][k] - a[j][k] * t) % mod; }
son’s rule. The error should be proportional to h4 , although in practice you swap(a[i], a[j]); if (r == -1) return false;
will want to verify that the result is stable to desired precision when epsilon ans *= -1; pivot(r, s);
changes. 4756fc, 7 lines } }
} }
template<class F>
ans = ans * a[i][i] % mod;
double quad(double a, double b, F f, const int n = 1000) {
if (!ans) return 0; T solve(vd &x) {
double h = (b - a) / 2 / n, v = f(a) + f(b);
} int r = 0;
rep(i,1,n*2)
return (ans + mod) % mod; rep(i,1,m) if (D[i][n+1] < D[r][n+1]) r = i;
v += f(a + i*h) * (i&1 ? 4 : 2);
} if (D[r][n+1] < -eps) {
return v * h / 3;
} pivot(r, n);
if (!simplex(2) || D[m+1][n+1] < -eps) return -inf;
Simplex.h rep(i,0,m) if (B[i] == -1) {
IntegrateAdaptive.h Description: Solves a general linear maximization problem: maximize cT x int s = 0;
Description: Fast integration using an adaptive Simpson’s rule. subject to Ax ≤ b, x ≥ 0. Returns -inf if there is no solution, inf if there rep(j,1,n+1) ltj(D[i]);
Usage: double sphereVolume = quad(-1, 1, [](double x) { are arbitrarily good solutions, or the maximum value of cT x otherwise. The pivot(i, s);
return quad(-1, 1, [&](double y) { input vector is set to an optimal x (or in the unbounded case, an arbitrary }
return quad(-1, 1, [&](double z) { solution fulfilling the constraints). Numerical stability is not guaranteed. For }
return x*x + y*y + z*z < 1; });});}); 92dd79, 15 lines
better performance, define variables such that x = 0 is viable. bool ok = simplex(1); x = vd(n);
Usage: vvd A = {{1,-1}, {-1,1}, {-1,-2}}; rep(i,0,m) if (B[i] < n) x[B[i]] = D[i][n+1];
typedef double d; vd b = {1,1,-4}, c = {-1,-1}, x; return ok ? D[m][n+1] : inf;
#define S(a,b) (f(a) + 4*f((a+b) / 2) + f(b)) * (b-a) / 6 T val = LPSolver(A, b, c).solve(x); }
Time: O (N M ∗ #pivots), where a pivot may be e.g. an edge relaxation. };
template <class F> O (2n ) in the general case.
d rec(F& f, d a, d b, d eps, d S) { aa8530, 68 lines
d c = (a + b) / 2; typedef double T; // long double , Rational , double + mod<P>...
d S1 = S(a, c), S2 = S(c, b), T = S1 + S2; typedef vector<T> vd;
if (abs(T - S) <= 15 * eps || b - a < 1e-10) typedef vector<vd> vvd;
KTH SolveLinear2 SolveLinearBinary MatrixInverse Tridiagonal FastFourierTransform 7
SolveLinear.h for (br=i; br<n; ++br) if (A[br].any()) break; }
Description: Solves A ∗ x = b. If there are multiple solutions, an arbitrary if (br == n) {
one is returned. Returns rank, or -1 if no solutions. Data in A and b is lost. rep(j,i,n) if(b[j]) return -1;
Time: O n2 m break;
Tridiagonal.h
44c9ab, 38 lines Description: x = tridiagonal(d, p, q, b) solves the equation system
}
typedef vector<double> vd; int bc = (int)A[br]._Find_next(i-1);
const double eps = 1e-12; swap(A[i], A[br]);

b0
 
d0 p0 0 0 ··· 0

x0

swap(b[i], b[br]);  b1   q0 d1 p1 0 ··· 0  x1 
int solveLinear(vector<vd>& A, vd& b, vd& x) { swap(col[i], col[bc]);

 b2 

 0
 q1 d2 p2 ··· 0 
 x2 

int n = sz(A), m = sz(x), rank = 0, br, bc; rep(j,0,n) if (A[j][i] != A[j][bc]) {
 b3 = .
 
. .
 x3 .


 . . .. .. .. .

if (n) assert(sz(A[0]) == m); A[j].flip(i); A[j].flip(bc);

.

 . . . . . .

.

. .
   
vi col(m); iota(all(col), 0); }  .   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
rep(i,0,n) { b[j] ˆ= b[i];
double v, bv = 0; A[j] ˆ= A[i];
rep(r,i,n) rep(c,i,m) This is useful for solving problems on the type
}
if ((v = fabs(A[r][c])) > bv) rank++;
br = r, bc = c, bv = v; ai = bi ai−1 + ci ai+1 + di , 1 ≤ i ≤ n,
}
if (bv <= eps) {
rep(j,i,n) if (fabs(b[j]) > eps) return -1; x = bs(); where a0 , an+1 , bi , ci and di are known. a can then be obtained from
break; for (int i = rank; i--;) {
} if (!b[i]) continue; {ai } = tridiagonal({1, −1, −1, ..., −1, 1}, {0, c1 , c2 , . . . , cn },
swap(A[i], A[br]); x[col[i]] = 1;
swap(b[i], b[br]); {b1 , b2 , . . . , bn , 0}, {a0 , d1 , d2 , . . . , dn , an+1 }).
rep(j,0,i) b[j] ˆ= A[j][i];
swap(col[i], col[bc]); }
rep(j,0,n) swap(A[j][i], A[j][bc]); return rank; // ( multiple solutions i f rank < m) Fails if the solution is not unique.
bv = 1/A[i][i]; } If |di | > |pi | + |qi−1 | for all i, or |di | > |pi−1 | + |qi |, or the matrix is positive
rep(j,i+1,n) { definite, the algorithm is numerically stable and neither tr nor the check for
double fac = A[j][i] * bv; diag[i] == 0 is needed.
b[j] -= fac * b[i]; MatrixInverse.h Time: O (N ) 8f9fa8, 26 lines
rep(k,i+1,m) A[j][k] -= fac*A[i][k]; Description: Invert matrix A. Returns rank; result is stored in A unless
} singular (rank < n). Can easily be extended to prime moduli; for prime typedef double T;
vector<T> tridiagonal(vector<T> diag, const vector<T>& super,
rank++; powers, repeatedly set A−1 = A−1 (2I − AA−1 ) (mod pk ) where A−1 starts
} const vector<T>& sub, vector<T> b) {
as the inverseof A mod p, and k is doubled in each step.
int n = sz(b); vi tr(n);
Time: O n3
x.assign(m, 0); ebfff6, 35 lines rep(i,0,n-1) {
for (int i = rank; i--;) { int matInv(vector<vector<double>>& A) { if (abs(diag[i]) < 1e-9 * abs(super[i])) { // diag [ i ] == 0
b[i] /= A[i][i]; int n = sz(A); vi col(n); b[i+1] -= b[i] * diag[i+1] / super[i];
x[col[i]] = b[i]; vector<vector<double>> tmp(n, vector<double>(n)); if (i+2 < n) b[i+2] -= b[i] * sub[i+1] / super[i];
rep(j,0,i) b[j] -= A[j][i] * b[i]; rep(i,0,n) tmp[i][i] = 1, col[i] = i; diag[i+1] = sub[i]; tr[++i] = 1;
} } else {
return rank; // ( multiple solutions i f rank < m) rep(i,0,n) { diag[i+1] -= super[i]*sub[i]/diag[i];
} 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])) }
SolveLinear2.h r = j, c = k; for (int i = n; i--;) {
Description: To get all uniquely determined values of x back from Solve- if (fabs(A[r][c]) < 1e-12) return i; if (tr[i]) {
Linear, make the following changes: A[i].swap(A[r]); tmp[i].swap(tmp[r]); swap(b[i], b[i-1]);
"SolveLinear.h" 08e495, 7 lines rep(j,0,n) diag[i-1] = diag[i];
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]; }
}
SolveLinearBinary.h rep(j,i+1,n) A[i][j] /= v;
Description: Solves Ax = b over F2 . If there are multiple solutions, one is rep(j,0,n) tmp[i][j] /= v; 4.1 Fourier transforms
returned arbitrarily. Returns rank, or -1 if no solutions. Destroys A and b. A[i][i] = 1;
Time: O n2 m
 } FastFourierTransform.h
fa2d7a, 34 lines
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
Useful for convolution: conv(a, b) = c, where c[x] = a[i]b[x − i]. For
double v = A[j][i]; convolution of complex numbers or more than two vectors: FFT, multiply
int solveLinear(vector<bs>& A, vi& b, bs& x, int m) { rep(k,0,n) tmp[j][k] -= v*tmp[i][k]; pointwise, divide by n, reverse(start+1, end), FFT back. For integers, con-
int n = sz(A), rank = 0, br; } sider using a number-theoretic transform instead, to avoid rounding issues.
assert(m <= sz(x)); Time: O (N log N ) with N = |A| + |B| − 1 (∼1s for N = 222 )13a407, 32 lines
vi col(m); iota(all(col), 0); rep(i,0,n) rep(j,0,n) A[col[i]][col[j]] = tmp[i][j];
rep(i,0,n) { return n; typedef complex<double> C;
KTH NumberTheoreticTransform FastSubsetTransform ModularArithmetic ModInverse ModPow ModSum ModMulLL ModSqrt 8
typedef vector<double> vd; ntt(out, rt, rev, n); ll modpow(ll b, ll e) {
return {out.begin(), out.begin() + s}; ll ans = 1;
void fft(vector<C> &a, vector<C> &rt, vi& rev, int n) { } for (; e; b = b * b % mod, e /= 2)
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]); if (e & 1) ans = ans * b % mod;
for (int k = 1; k < n; k *= 2) return ans;
for (int i = 0; i < n; i += 2 * k) rep(j,0,k) {
FastSubsetTransform.h }
Description: Transform to a basis with fast convolutions of the form
C z = rt[j+k] * a[i+j+k]; // (25% f a s t e r i f hand−r o l l e d ) X
a[i + j + k] = a[i + j] - z; c[z] = a[x] · b[y], where ⊕ is one of AND, OR, XOR. The size
a[i + j] += z;
z=x⊕y
of a must be a power of two.
ModSum.h
} Description: Sums of mod’ed arithmetic progressions.
Time: O (N log N ) Pto−1
}
3de473, 16 lines modsum(to, c, k, m) = i=0 (ki + c)%m. divsum is similar but for
void FST(vi& a, bool inv) { floored division.
vd conv(const vd& a, const vd& b) { for (int n = sz(a), step = 1; step < n; step *= 2) { Time: log(m), with a large constant. 5c5bc5, 16 lines
if (a.empty() || b.empty()) return {}; for (int i = 0; i < n; i += 2 * step) rep(j,i,i+step) {
typedef unsigned long long ull;
vd res(sz(a) + sz(b) - 1); int &u = a[j], &v = a[j + step]; tie(u, v) =
ull sumsq(ull to) { return to / 2 * ((to-1) | 1); }
int L = 32 - __builtin_clz(sz(res)), n = 1 << L; inv ? pii(v - u, u) : pii(v, u + v); // AND
vector<C> in(n), out(n), rt(n, 1); vi rev(n); inv ? pii(v, u - v) : pii(u + v, u); // OR
ull divsum(ull to, ull c, ull k, ull m) {
rep(i,0,n) rev[i] = (rev[i/2] | (i&1) << L) / 2; pii(u + v, u - v); // XOR
ull res = k / m * sumsq(to) + c / m * to;
for (int k = 2; k < n; k *= 2) { }
k %= m; c %= m;
C z[] = {1, polar(1.0, M_PI / k)}; }
if (!k) return res;
rep(i,k,2*k) rt[i] = rt[i/2] * z[i&1]; if (inv) trav(x, a) x /= sz(a); // XOR only
ull to2 = (to * k + c) / m;
} }
return res + (to - 1) * to2 - divsum(to2, m-1 - c, m, k);
copy(all(a), begin(in)); vi conv(vi a, vi b) {
}
rep(i,0,sz(b)) in[i].imag(b[i]); FST(a, 0); FST(b, 0);
fft(in, rt, rev, n); rep(i,0,sz(a)) a[i] *= b[i];
ll modsum(ull to, ll c, ll k, ll m) {
trav(x, in) x *= x; FST(a, 1); return a;
c = ((c % m) + m) % m;
rep(i,0,n) out[i] = in[-i & (n - 1)] - conj(in[i]); }
k = ((k % m) + m) % m;
fft(out, rt, rev, n); return to * c + k * sumsq(to) - m * divsum(to, c, k, m);
rep(i,0,sz(res)) res[i] = imag(out[i]) / (4*n); }
return res; Number theory (5)
}
5.1 Modular arithmetic ModMulLL.h
Description: Calculate a · b mod c (or ab mod c) for 0 ≤ a, b < c < 263 .
NumberTheoreticTransform.h Time: O (1) for mod mul, O (log b) for mod pow 88c37a, 12 lines
Description: Can be used for convolutions modulo specific nice primes of ModularArithmetic.h typedef unsigned long long ull;
the form 2a b + 1, where the convolution result has size at most 2a . For other Description: Operators for modular arithmetic. You need to set mod to
some number first and then you can use the structure. typedef long double ld;
primes/integers, use three different primes and combine with CRT. Inputs ull mod_mul(ull a, ull b, ull M) {
must be in [0, mod). "euclid.h" 35bfea, 18 lines
ll ret = a * b - M * ull(ld(a) * ld(b) / ld(M));
Time: O (N log N ) const ll mod = 17; // change to something e l s e return ret + M * (ret < 0) - M * (ret >= (ll)M);
"../number-theory/ModPow.h" d75aad, 32 lines struct Mod { }
const ll mod = (119 << 23) + 1, root = 62; // = 998244353 ll x; ull mod_pow(ull b, ull e, ull mod) {
// For p < 2ˆ30 there i s also e . g . 5 << 25, 7 << 26, 479 << 21 Mod(ll xx) : x(xx) {} ull ans = 1;
// and 483 << 21 (same root ) . The l a s t two are > 10ˆ9. Mod operator+(Mod b) { return Mod((x + b.x) % mod); } for (; e; b = mod_mul(b, b, mod), e /= 2)
Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); } if (e & 1) ans = mod_mul(ans, b, mod);
typedef vector<ll> vl; Mod operator*(Mod b) { return Mod((x * b.x) % mod); } return ans;
void ntt(vl& a, vl& rt, vl& rev, int n) { Mod operator/(Mod b) { return *this * invert(b); } }
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]); Mod invert(Mod a) {
for (int k = 1; k < n; k *= 2) ll x, y, g = euclid(a.x, mod, x, y);
for (int i = 0; i < n; i += 2 * k) rep(j,0,k) { assert(g == 1); return Mod((x + mod) % mod); ModSqrt.h
ll z = rt[j + k] * a[i + j + k] % mod, &ai = a[i + j]; } Description: Tonelli-Shanks algorithm for modular square roots.
Time: O log2 p worst case, often O (log p)

a[i + j + k] = (z > ai ? ai - z + mod : ai - z); Mod operatorˆ(ll e) {
ai += (ai + z >= mod ? z - mod : z); if (!e) return Mod(1); "ModPow.h" 19a793, 24 lines

} Mod r = *this ˆ (e / 2); r = r * r; ll sqrt(ll a, ll p) {


} return e&1 ? *this * r : r; a %= p; if (a < 0) a += p;
} if (a == 0) return 0;
vl conv(const vl& a, const vl& b) { }; assert(modpow(a, (p-1)/2, p) == 1);
if (a.empty() || b.empty()) if (p % 4 == 3) return modpow(a, (p+1)/4, p);
return {}; ModInverse.h // aˆ(n+3)/8 or 2ˆ(n+3)/8 ∗ 2ˆ(n−1)/4 works i f p % 8 == 5
int s = sz(a)+sz(b)-1, B = 32 - __builtin_clz(s), n = 1 << B; Description: Pre-computation of modular inverses. Assumes LIM ≤ mod ll s = p - 1, n = 2;
vl L(a), R(b), out(n), rt(n, 1), rev(n); and that mod is a prime. int r = 0, m;
6f684f, 3 lines
L.resize(n), R.resize(n); while (s % 2 == 0)
rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << B) / 2; const ll mod = 1000000007, LIM = 200000; ++r, s /= 2;
ll curL = mod / 2, inv = modpow(n, mod - 2); ll* inv = new ll[LIM] - 1; inv[1] = 1; while (modpow(n, (p - 1) / 2, p) != p - 1) ++n;
for (int k = 2; k < n; k *= 2) { rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[mod % i] % mod; ll x = modpow(a, (s + 1) / 2, p);
ll z[] = {1, modpow(root, curL /= 2)}; ll b = modpow(a, s, p), g = modpow(n, s, p);
rep(i,k,2*k) rt[i] = rt[i / 2] * z[i & 1] % mod; ModPow.h for (;; r = m) {
} b83e45, 8 lines ll t = b;
ntt(L, rt, rev, n); ntt(R, rt, rev, n); const ll mod = 1000000007; // f a s t e r i f const for (m = 0; m < r && t != 1; ++m)
rep(i,0,n) out[-i & (n-1)] = L[i] * R[i] % mod * inv % mod; t = t * t % p;
KTH eratosthenes MillerRabin Factor euclid Euclid phiFunction ContinuedFractions FracBinarySearch 9
if (m == 0) return x; l.insert(l.end(), all(r)); for(int i = 3; i < LIM; i += 2) if(phi[i] == i)
ll gs = modpow(g, 1LL << (r - m - 1), p); return l; for(int j = i; j < LIM; j += i) phi[j] -= phi[j] / i;
g = gs * gs % p; } }
x = x * gs % p;
b = b * g % p;
} 5.3 Divisibility 5.4 Fractions
}
euclid.h ContinuedFractions.h
Description: Finds the Greatest Common Divisor to the integers a and b. Description: Given N and a real number x ≥ 0, finds the closest rational
5.2 Primality Euclid also finds two integers x and y, such that ax + by = gcd(a, b). If a approximation p/q with p, q ≤ N . It will obey |p/q − x| ≤ 1/qN .
and b are coprime, then x is the inverse of a (mod b). 63e6f8, 7 lines For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . (pk /qk alternates
eratosthenes.h ll gcd(ll a, ll b) { return __gcd(a, b); }
between > x and < x.) If x is rational, y eventually becomes ∞; if x is the
Description: Prime sieve for generating all primes up to a certain limit. root of a degree 2 polynomial the a’s eventually become cyclic.
isprime[i] is true iff i is a prime. Time: O (log N ) dd6c5e, 21 lines
ll euclid(ll a, ll b, ll &x, ll &y) {
Time: lim=100’000’000 ≈ 0.8 s. Runs 30% faster if only odd indices are
if (b) { ll d = euclid(b, a % b, y, x); typedef double d; // for N ∼ 1e7 ; long double for N ∼ 1e9
stored. 29cd0a, 11 lines return y -= a/b * x, d; } pair<ll, ll> approximate(d x, ll N) {
const int MAX_PR = 5’000’000; return x = 1, y = 0, a; ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; d y = x;
bitset<MAX_PR> isprime; } for (;;) {
vi eratosthenes_sieve(int lim) { ll lim = min(P ? (N-LP) / P : inf, Q ? (N-LQ) / Q : inf),
isprime.set(); isprime[0] = isprime[1] = 0; a = (ll)floor(y), b = min(a, lim),
for (int i = 4; i < lim; i += 2) isprime[i] = 0;
Euclid.java NP = b*P + LP, NQ = b*Q + LQ;
Description: Finds {x, y, d} s.t. ax + by = d = gcd(a, b). 6aba01, 11 lines
for (int i = 3; i*i < lim; i += 2) if (isprime[i]) if (a > b) {
for (int j = i*i; j < lim; j += i*2) isprime[j] = 0; static BigInteger[] euclid(BigInteger a, BigInteger b) { // I f b > a/2, we have a semi−convergent that gives us a
vi pr; BigInteger x = BigInteger.ONE, yy = x; // better approximation ; i f b = a/2, we ∗may∗ have one .
rep(i,2,lim) if (isprime[i]) pr.push_back(i); BigInteger y = BigInteger.ZERO, xx = y; // Return {P, Q} here for a more canonical approximation .
return pr; while (b.signum() != 0) { return (abs(x - (d)NP / (d)NQ) < abs(x - (d)P / (d)Q)) ?
} BigInteger q = a.divide(b), t = b; make_pair(NP, NQ) : make_pair(P, Q);
b = a.mod(b); a = t; }
t = xx; xx = x.subtract(q.multiply(xx)); x = t; if (abs(y = 1/(y - (d)a)) > 3*N) {
MillerRabin.h t = yy; yy = y.subtract(q.multiply(yy)); y = t; return {NP, NQ};
Description: Deterministic Miller-Rabin primality test. Guaranteed to }
}
work for numbers up to 264 ; for larger numbers, extend A randomly. LP = P; P = NP;
return new BigInteger[]{x, y, a};
Time: 7 times the complexity of ab mod c. LQ = Q; Q = NQ;
}
"ModMulLL.h" 6ab8e1, 12 lines
}
bool isPrime(ull n) { }
if (n < 2 || n % 6 % 4 != 1) return n - 2 < 2; 5.3.1 Bézout’s identity
ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
s = __builtin_ctzll(n-1), d = n >> s; FracBinarySearch.h
trav(a, A) { // ˆ count t r a i l i n g zeroes For a 6=, b 6= 0, then d = gcd(a, b) is the smallest positive Description: Given f and N , finds the smallest fraction p/q ∈ [0, 1] such
that f (p/q) is true, and p, q ≤ N . You may want to throw an exception from
ull p = mod_pow(a, d, n), i = s; integer for which there are integer solutions to f if it finds an exact solution, in which case N can be removed.
while (p != 1 && p != n - 1 && a % n && i--)
p = mod_mul(p, p, n); Usage: fracBS([](Frac f) { return f.p>=3*f.q; }, 10); // {1,3}
if (p != n-1 && i != s) return 0; ax + by = d Time: O (log(N )) 27ab3e, 25 lines
} struct Frac { ll p, q; };
return 1;
} If (x, y) is one solution, then all solutions are given by template<class F>
  Frac fracBS(F f, ll N) {
Factor.h kb ka bool dir = 1, A = 1, B = 1;
Description: Pollard-rho randomized factorization algorithm. Returns x+ ,y − , k∈Z Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to search (0 , N]
gcd(a, b) gcd(a, b) if (f(lo)) return lo;
 ofa number, in arbitrary order (e.g. 2299 -> {11, 19, 11}).
prime factors
assert(f(hi));
Time: O n1/4 gcd calls, less for numbers with small factors. while (A || B) {
f5adaa, 18 lines
"ModMulLL.h", "MillerRabin.h"
phiFunction.h ll adv = 0, step = 1; // move hi i f dir , e l s e lo
ull pollard(ull n) { Description: Euler’s totient or Euler’s phi function is defined as φ(n) := # for (int si = 0; step; (step *= 2) >>= si) {
auto f = [n](ull x) { return (mod_mul(x, x, n) + 1) % n; }; of positive integers ≤ n that are coprime with n. The cototient is n − φ(n). adv += step;
if (!(n & 1)) return 2; φ(1) = 1, p prime ⇒ φ(pk ) = (p − 1)pk−1 , m, n coprime ⇒ φ(mn) = Frac mid{lo.p * adv + hi.p, lo.q * adv + hi.q};
for (ull i = 2;; i++) { k k r then φ(n) = (p − 1)pk1 −1 ...(p − 1)pkr −1 .
if (abs(mid.p) > N || mid.q > N || dir == !f(mid)) {
ull x = i, y = f(x), p; φ(m)φ(n). Q If n = p1 1 p2 2 ...pk
r 1 1 r r adv -= step; si = 2;
while ((p = __gcd(n + y - x, n)) == 1) φ(n) = n · p|n (1 − 1/p). }
P P
x = f(x), y = f(f(y)); d|n φ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nφ(n)/2, n > 1 }
if (p != n) return p; Euler’s thm: a, n coprime ⇒ aφ(n) ≡ 1 (mod n). hi.p += lo.p * adv;
} Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 (mod p) ∀a. hi.q += lo.q * adv;
} cf7d6d, 8 lines dir = !dir;
vector<ull> factor(ull n) { const int LIM = 5000000; swap(lo, hi);
if (n == 1) return {}; int phi[LIM]; A = B; B = !!adv;
if (isPrime(n)) return {n}; }
ull x = pollard(n); void calculatePhi() { return dir ? hi : lo;
auto l = factor(x), r = factor(n / x); rep(i,0,LIM) phi[i] = i&1 ? i : i/2; }
KTH chinese IntPerm binomialModPrime multinomial 10
5.5 Chinese remainder theorem Combinatorial (6) 6.2 Partitions and subsets

chinese.h 6.1 Permutations 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 6.1.1 Factorial 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
numbers must be less than 231 if you have Z = unsigned long long. n 123 4 5 6 7 8 9 10 disregarding the order of the summands.
Time: log(m + n)
n! 1 2 6 24 120 720 5040 40320 362880 3628800 X
(−1)k+1 p(n − k(3k − 1)/2)
"euclid.h" da3099, 13 lines
template<class Z> Z chinese(Z a, Z m, Z b, Z n) { n 11 12 13 14 15 16 17 p(0) = 1, p(n) =
Z x, y; euclid(m, n, x, y); n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14 k∈Z\{0}
Z ret = a * (y + m) % m * n + b * (x + n) % n * m;
if (ret >= m * n) ret -= m * n; n 20 25 30 40 50 100 150 171 √
return ret;
n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL MAX p(n) ∼ 0.145/n · exp(2.56 n)
}

template<class Z> Z chinese_common(Z a, Z m, Z b, Z n) { IntPerm.h n 0 1 2 3 4 5 6 7 8 9 20 50 100


Description: Permutation -> integer conversion. (Not order preserving.)
Z d = gcd(m, n);
Time: O (n)
p(n) 1 1 2 3 5 7 11 15 22 30 627 ∼2e5 ∼2e8
if (((b -= a) %= n) < 0) b += n; e1b8ea, 6 lines
if (b % d) return -1; // No solution int permToInt(vi& v) {
return d * chinese(Z(0), m/d, b/d, n/d) + a; int use = 0, i = 0, r = 0;
6.2.2 Binomials
} trav(x, v) r = r * ++i + __builtin_popcount(use & -(1 << x)),
use |= 1 << x; // (note : minus, not ∼! ) binomialModPrime.h
return r; 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
n k ni
≡ (mod p). fact and invfact must hold pre-computed facto-
5.6 Pythagorean Triples m i=0 mi
rials / inverse factorials, e.g. from ModInverse.h.
6.1.2 Cycles

Time: O logp n 81845f, 10 lines
The Pythagorean triples are uniquely generated by ll chooseModP(ll n, ll m, int p, vi& fact, vi& invfact) {
Let gS (n) be the number of n-permutations whose cycle ll c = 1;
lengths all belong to the set S. Then while (n || m) {
a = k · (m2 − n2 ), b = k · (2mn), c = k · (m2 + n2 ), ll a = n % p, b = m % p;

!
if (a < b) return 0;
X xn X xn
c = c * fact[a] % p * invfact[b] % p * invfact[a - b] % p;
gS (n) = exp
with m > n > 0, k > 0, m⊥n, and either m or n even. n=0
n! n n /= p; m /= p;
n∈S }
return c;
}
6.1.3 Derangements
5.7 Primes Permutations of a set such that none of the elements appear multinomial.h P
k + · · · + k  ( ki )!
1 n
in their original position. Description: Computes = .
p = 962592769 is such that 221 | p − 1, which may be useful.  
k1 , k2 , . . . , kn k1 !k2 !...kn ! a0a312, 6 lines

For hashing use 970592641 (31-bit number), 31443539979727 D(n) = (n−1)(D(n−1)+D(n−2)) = nD(n−1)+(−1)n = n! llllmultinomial(vi& v) {
c = 1, m = v.empty() ? 1 : v[0];
(45-bit), 3006703054056749 (52-bit). There are 78498 primes e rep(i,1,sz(v)) rep(j,0,v[i])
c = c * ++m / (j+1);
less than 1 000 000. return c;
6.1.4 Burnside’s lemma }
Primitive roots exist modulo any prime power pa , except for Given a group G of symmetries and a set X, the number of
p = 2, a > 2, and there are φ(φ(pa )) many. For p = 2, a > 2, elements of X up to symmetry equals 6.3 General purpose numbers
the group Z× 2a is instead isomorphic to Z2 × Z2a−2 .
1 X
|X g |, 6.3.1 Stirling numbers of the first kind
|G|
g∈G
5.8 Estimates Number of permutations on n items with k cycles.
where X g are the elements fixed by g (g.x = x).
P
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
d|n d = O(n log log n). Pn
can ignore rotational symmetry using G = Zn to get k
k=0 c(n, k)x = x(x + 1) . . . (x + n − 1)
The number of divisors of n is at most around 100 for n−1
n < 5e4, 500 for n < 1e7, 2000 for n < 1e10, 200 000 for 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).
n < 1e19. 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) rep(i,0,n) if (indeg[i] == 0) q.push(-i);
int nr = 0;
Number of permutations π ∈ Sn in which exactly k elements 7.1 Fundamentals while (q.size() > 0) {
int i = -q.front(); // top () for priority queue
are greater than the previous element. k j:s s.t. idx[i] = nr++;
π(j) > π(j + 1), k + 1 j:s s.t. π(j) ≥ j, k j:s s.t. BellmanFord.h q.pop();
Description: Calculates shortest paths from s in a graph that might have trav(e, edges[i])
π(j) > j. negative edge weights. Unreachable nodes get dist = inf; nodes reachable if (--indeg[e] == 0) q.push(-e);
through negative-weight cycles get dist = -inf. Assumes V 2 max |wi | < ∼263 . }
return nr == n;
E(n, k) = (n − k)E(n − 1, k − 1) + (k + 1)E(n − 1, k) Time: O (V E) 53f20b, 23 lines }
const ll inf = LLONG_MAX;
E(n, 0) = E(n, n − 1) = 1 struct Ed { int a, b, w, s() { return a < b ? a : -a; }};

k  
struct Node { ll dist = inf; int prev = -1; }; 7.2 Euler walk
X n+1 void bellmanFord(vector<Node>& nodes, vector<Ed>& eds, int s) {
E(n, k) = (−1)j (k + 1 − j)n nodes[s].dist = 0; EulerWalk.h
j=0
j sort(all(eds), [](Ed a, Ed b) { return a.s() < b.s(); }); Description: Eulerian undirected/directed path/cycle algorithm. Returns
a list of nodes in the Eulerian path/cycle with src at both start and end,
int lim = sz(nodes) / 2 + 2; // /3+100 with shuffled vertices or empty list if no cycle/path exists. To get edge indices back, also put
6.3.3 Stirling numbers of the second kind rep(i,0,lim) trav(ed, eds) { it->second in s (and then ret).
Node cur = nodes[ed.a], &dest = nodes[ed.b]; Time: O (E) where E is the number of edges. f8bd47, 27 lines
Partitions of n distinct elements into exactly k if (abs(cur.dist) == inf) continue;
struct V {
ll d = cur.dist + ed.w;
groups. if (d < dest.dist) { vector<pii> outs; // ( dest , edge index )
dest.prev = ed.a; int nins = 0;
};
S(n, k) = S(n − 1, k − 1) + kS(n − 1, k) dest.dist = (i < lim-1 ? d : -inf);
}
} vi euler_walk(vector<V>& nodes, int nedges, int src=0) {
int c = 0;
S(n, 1) = S(n, n) = 1 rep(i,0,lim) trav(e, eds) {
trav(n, nodes) c += abs(n.nins - sz(n.outs));
if (nodes[e.a].dist == -inf)
k   nodes[e.b].dist = -inf; if (c > 2) return {};
1 X k−j k vector<vector<pii>::iterator> its;
S(n, k) = (−1) jn }
trav(n, nodes)
k! j=0 j }
its.push_back(n.outs.begin());
vector<bool> eu(nedges);
FloydWarshall.h vi ret, s = {src};
6.3.4 Bell numbers Description: Calculates all-pairs shortest path in a directed graph that while(!s.empty()) {
might have negative edge weights. Input is an distance matrix m, where int x = s.back();
Total number of partitions of n distinct elements. B(n) = m[i][j] = inf if i and j are not adjacent. As output, m[i][j] is set to the 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;
1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, . . . . For p prime, through a negative-weight cycle. if(it == end) { ret.push_back(x); s.pop_back(); }
Time: O N 3

else { s.push_back(it->first); eu[it->second] = true; }
531245, 12 lines
B(pm + n) ≡ mB(n) + B(n + 1) (mod p) const ll inf = 1LL << 62;
}
if(sz(ret) != nedges+1)
void floydWarshall(vector<vector<ll>>& m) { ret.clear(); // No Eulerian cycles/paths .
int n = sz(m); // else , non−cycle i f ret . front () != ret . back ()
6.3.5 Catalan numbers rep(i,0,n) m[i][i] = min(m[i][i], 0LL); reverse(all(ret));
rep(k,0,n) rep(i,0,n) rep(j,0,n) return ret;
if (m[i][k] != inf && m[k][j] != inf) { }
      auto newDist = max(m[i][k] + m[k][j], -inf);
1 2n 2n 2n (2n)! m[i][j] = min(m[i][j], newDist);
Cn = = − = }
n+1 n n n+1 (n + 1)!n! 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;
2(2n + 1) X
C0 = 1, Cn+1 = Cn , Cn+1 = Ci Cn−i } PushRelabel.h
n+2 Description: Push-relabel using the highest label selection rule and the gap
TopoSort.h heuristic. Quite fast in practice. To obtain the actual flow, look at positive
Cn = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, . . . Description: Topological sorting. Given is an oriented graph. Output is an values only.
 √ 
ordering of vertices (array idx), such that there are edges only from left to Time: O V 2 E
• sub-diagonal monotone paths in an n × n grid. right. The function returns false if there is a cycle in the graph.
6c4045, 49 lines

typedef ll Flow;
• strings with n pairs of parenthesis, correctly nested. Time: O (|V | + |E|) 0582b8, 18 lines struct Edge {
• binary trees with with n + 1 leaves (0 or 2 children). template<class E, class I> int dest, back;
bool topo_sort(const E &edges, I &idx, int n) { Flow f, c;
• ordered trees with n + 1 vertices. vi indeg(n); };
• ways a convex polygon with n + 2 sides can be cut into rep(i,0,n)
trav(e, edges[i]) struct PushRelabel {
triangles by connecting vertices with straight lines. indeg[e]++; vector<vector<Edge>> g;
• permutations of [n] with no 3-term increasing subseq. queue<int> q; // use priority queue for l e x i c . smallest ans . vector<Flow> ec;
KTH MinCostMaxFlow EdmondsKarp MinCut GlobalMinCut 12
vector<Edge*> cur; red[to].push_back(from); T flow = 0;
vector<vi> hs; vi H; } vi par(sz(graph)), q = par;
PushRelabel(int n) : g(n), ec(n), cur(n), hs(2*n), H(n) {}
void path(int s) { for (;;) {
void add_edge(int s, int t, Flow cap, Flow rcap=0) { fill(all(seen), 0); fill(all(par), -1);
if (s == t) return; fill(all(dist), INF); par[source] = 0;
g[s].push_back({t, sz(g[t]), 0, cap}); dist[s] = 0; ll di; int ptr = 1;
g[t].push_back({s, sz(g[s])-1, 0, rcap}); q[0] = source;
} __gnu_pbds::priority_queue<pair<ll, int>> q;
vector<decltype(q)::point_iterator> its(N); rep(i,0,ptr) {
void add_flow(Edge& e, Flow f) { q.push({0, s}); int x = q[i];
Edge &back = g[e.dest][e.back]; trav(e, graph[x]) {
if (!ec[e.dest] && f) hs[H[e.dest]].push_back(e.dest); auto relax = [&](int i, ll cap, ll cost, int dir) { if (par[e.first] == -1 && e.second > 0) {
e.f += f; e.c -= f; ec[e.dest] += f; ll val = di - pi[i] + cost; par[e.first] = x;
back.f -= f; back.c += f; ec[back.dest] -= f; if (cap && val < dist[i]) { q[ptr++] = e.first;
} dist[i] = val; if (e.first == sink) goto out;
Flow maxflow(int s, int t) { par[i] = {s, dir}; }
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(); } return flow;
trav(e, g[s]) add_flow(e, e.c); }; out:
T inc = numeric_limits<T>::max();
for (int hi = 0;;) { while (!q.empty()) { for (int y = sink; y != source; y = par[y])
while (hs[hi].empty()) if (!hi--) return -ec[s]; s = q.top().second; q.pop(); inc = min(inc, graph[par[y]][y]);
int u = hs[hi].back(); hs[hi].pop_back(); seen[s] = 1; di = dist[s] + pi[s];
while (ec[u] > 0) // discharge u trav(i, ed[s]) if (!seen[i]) flow += inc;
if (cur[u] == g[u].data() + sz(g[u])) { relax(i, cap[s][i] - flow[s][i], cost[s][i], 1); for (int y = sink; y != source; y = par[y]) {
H[u] = 1e9; trav(i, red[s]) if (!seen[i]) int p = par[y];
trav(e, g[u]) if (e.c && H[u] > H[e.dest]+1) relax(i, flow[i][s], -cost[i][s], 0); if ((graph[p][y] -= inc) <= 0) graph[p].erase(y);
H[u] = H[e.dest]+1, cur[u] = &e; } graph[y][p] += inc;
if (++co[H[u]], !--co[hi] && hi < v) rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF); }
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}; 03261f, 31 lines
at positive values only. }
Time: Approximately O E 2
 pair<int, vi> GetMinCut(vector<vi>& weights) {
6915ce, 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) : EdmondsKarp.h rep(j,0,N) weights[j][prev] = weights[prev][j];
N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap), Description: Flow algorithm with guaranteed complexity O(V E 2 ). To get used[k] = true;
seen(N), dist(N), pi(N), par(N) {} edge flow values, compare capacities before and after, and take the positive cut.push_back(k);
values only. if (best_weight == -1 || w[k] < best_weight) {
void addEdge(int from, int to, ll cap, ll cost) { 979bb9, 35 lines best_cut = cut;
this->cap[from][to] = cap; template<class T> T edmondsKarp(vector<unordered_map<int, T>>& best_weight = w[k];
this->cost[from][to] = cost; graph, int source, int sink) { }
ed[from].push_back(to); assert(source != sink); } else {
KTH hopcroftKarp DFSMatching MinimumVertexCover WeightedMatching GeneralMatching 13
rep(j,0,N) Usage: vi btoa(m, -1); dfsMatching(g, btoa); v[j] = cost[0][j] - u[0];
w[j] += weights[k][j]; Time: O (V E) 6a3472, 22 lines
rep(i,1,n) v[j] = min(v[j], cost[i][j] - u[i]);
added[k] = true; }
} bool find(int j, vector<vi>& g, vi& btoa, vi& vis) {
} if (btoa[j] == -1) return 1; L = R = vi(n, -1);
} vis[j] = 1; int di = btoa[j]; rep(i,0,n) rep(j,0,n) {
return {best_weight, best_cut}; trav(e, g[di]) if (R[j] != -1) continue;
} if (!vis[e] && find(e, g, btoa, vis)) { if (zero(cost[i][j] - u[i] - v[j])) {
btoa[e] = di; L[i] = j;
return 1; R[j] = i;
}
7.4 Matching return 0;
mated++;
break;
} }
hopcroftKarp.h int dfsMatching(vector<vi>& g, vi& btoa) { }
Description: Fast bipartite matching algorithm. Graph g should be a list vi vis;
of neighbors of the left partition, and btoa should be a vector full of -1’s of rep(i,0,sz(g)) { for (; mated < n; mated++) { // u n t i l solution i s f e a s i b l e
the same size as the right partition. Returns the size of the matching. btoa[i] vis.assign(sz(btoa), 0); int s = 0;
will be the match for vertex i on the right side, or −1 if it’s not matched. trav(j,g[i]) while (L[s] != -1) s++;
Usage: vi btoa(m, -1); hopcroftKarp(g, btoa); if (find(j, g, btoa, vis)) { fill(all(dad), -1);
√
btoa[j] = i;

Time: O VE fill(all(seen), 0);
536939, 42 lines break; rep(k,0,n)
bool dfs(int a, int L, vector<vi>& g, vi& btoa, vi& A, vi& B) { } dist[k] = cost[s][k] - u[s] - v[k];
if (A[a] != L) return 0; }
A[a] = -1; return sz(btoa) - (int)count(all(btoa), -1); int j = 0;
trav(b, g[a]) if (B[b] == L + 1) { } for (;;) {
B[b] = 0; j = -1;
if (btoa[b] == -1 || dfs(btoa[b], L + 1, g, btoa, A, B)) rep(k,0,n){
return btoa[b] = a, 1; MinimumVertexCover.h if (seen[k]) continue;
} Description: Finds a minimum vertex cover in a bipartite graph. The size if (j == -1 || dist[k] < dist[j]) j = k;
return 0; is the same as the size of a maximum matching, and the complement is a }
} maximum independent set. seen[j] = 1;
"DFSMatching.h" d0b3f2, 20 lines
int i = R[j];
int hopcroftKarp(vector<vi>& g, vi& btoa) { vi cover(vector<vi>& g, int n, int m) { if (i == -1) break;
int res = 0; vi match(m, -1); rep(k,0,n) {
vi A(g.size()), B(btoa.size()), cur, next; int res = dfsMatching(g, match); if (seen[k]) continue;
for (;;) { vector<bool> lfound(n, true), seen(m); auto new_dist = dist[j] + cost[i][k] - u[i] - v[k];
fill(all(A), 0); trav(it, match) if (it != -1) lfound[it] = false; if (dist[k] > new_dist) {
fill(all(B), 0); vi q, cover; dist[k] = new_dist;
cur.clear(); rep(i,0,n) if (lfound[i]) q.push_back(i); dad[k] = j;
trav(a, btoa) if(a != -1) A[a] = -1; while (!q.empty()) { }
rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a); int i = q.back(); q.pop_back(); }
for (int lay = 1;; lay++) { lfound[i] = 1; }
bool islast = 0; trav(e, g[i]) if (!seen[e] && match[e] != -1) {
next.clear(); seen[e] = true; rep(k,0,n) {
trav(a, cur) trav(b, g[a]) { q.push_back(match[e]); if (k == j || !seen[k]) continue;
if (btoa[b] == -1) { } auto w = dist[k] - dist[j];
B[b] = lay; } v[k] += w, u[R[k]] -= w;
islast = 1; rep(i,0,n) if (!lfound[i]) cover.push_back(i); }
} rep(i,0,m) if (seen[i]) cover.push_back(n+i); u[s] += dist[j];
else if (btoa[b] != a && !B[b]) { assert(sz(cover) == res);
B[b] = lay; return cover; while (dad[j] >= 0) {
next.push_back(btoa[b]); } int d = dad[j];
} R[j] = R[d];
} L[R[j]] = j;
if (islast) break; WeightedMatching.h j = d;
if (next.empty()) return res; Description: Min cost bipartite matching. Negate costs for max cost. }
trav(a, next) A[a] = lay; Time: O N 3 055ca9, 75 lines R[j] = s;
cur.swap(next); L[s] = j;
} typedef vector<double> vd;
}
rep(a,0,sz(g)) bool zero(double x) { return fabs(x) < 1e-10; }
auto value = vd(1)[0];
res += dfs(a, 0, g, btoa, A, B); double MinCostMatching(const vector<vd>& cost, vi& L, vi& R) {
rep(i,0,n) value += cost[i][L[i]];
} int n = sz(cost), mated = 0;
return value;
} vd dist(n), u(n), v(n);
}
vi dad(n), seen(n);

DFSMatching.h rep(i,0,n) {
GeneralMatching.h
Description: Simple bipartite matching algorithm. Graph g should be a list u[i] = cost[i][0];
Description: Matching for general graphs. Fails with probability N/mod.
of neighbors of the left partition, and btoa should be a vector full of -1’s of rep(j,1,n) u[i] = min(u[i], cost[i][j]);
Time: O N 3
the same size as the right partition. Returns the size of the matching. btoa[i] }
"../numerical/MatrixInverse-mod.h" bb8be4, 40 lines
will be the match for vertex i on the right side, or −1 if it’s not matched. rep(j,0,n) {
KTH SCC BiconnectedComponents 2sat MaximalCliques 14
vector<pii> generalMatching(int N, vector<pii>& ed) { } Time: O (N + E), where N is the number of boolean variables, and E is the
vector<vector<ll>> mat(N, vector<ll>(N)), A; return val[j] = low; number of clauses. 0911c1, 56 lines
trav(pa, ed) { }
int a = pa.first, b = pa.second, r = rand() % mod; template<class G, class F> void scc(G& g, F f) { struct TwoSat {
mat[a][b] = r, mat[b][a] = (mod - r) % mod; int n = sz(g); int N;
} val.assign(n, 0); comp.assign(n, -1); vector<vi> gr;
Time = ncomps = 0; vi values; // 0 = false , 1 = true
int r = matInv(A = mat), M = 2*N - r, fi, fj; rep(i,0,n) if (comp[i] < 0) dfs(i, g, f);
assert(r % 2 == 0); } TwoSat(int n = 0) : N(n), gr(2*n) {}

if (M != N) do { int add_var() { // ( optional )


mat.resize(M, vector<ll>(M)); BiconnectedComponents.h gr.emplace_back();
rep(i,0,N) { Description: Finds all biconnected components in an undirected graph, and gr.emplace_back();
mat[i].resize(M); runs a callback for the edges in each. In a biconnected component there are return N++;
rep(j,N,M) { at least two distinct paths between any two nodes. Note that a node can be }
int r = rand() % mod; in several components. An edge which is not in a component is a bridge, i.e.,
mat[i][j] = r, mat[j][i] = (mod - r) % mod; not part of any cycle. void either(int f, int j) {
} Usage: int eid = 0; ed.resize(N); f = max(2*f, -1-2*f);
} for each edge (a,b) { j = max(2*j, -1-2*j);
} while (matInv(A = mat) != M); ed[a].emplace back(b, eid); gr[f].push_back(jˆ1);
ed[b].emplace back(a, eid++); } gr[j].push_back(fˆ1);
vi has(M, 1); vector<pii> ret; bicomps([&](const vi& edgelist) {...}); }
rep(it,0,M/2) { Time: O (E + V ) void set_value(int x) { either(x, x); }
cca7e6, 33 lines
rep(i,0,M) if (has[i])
vi num, st; void at_most_one(const vi& li) { // ( optional )
rep(j,i+1,M) if (A[i][j] && mat[i][j]) {
vector<vector<pii>> ed; if (sz(li) <= 1) return;
fi = i; fj = j; goto done;
int Time; int cur = ∼li[0];
} assert(0); done:
template<class F> rep(i,2,sz(li)) {
if (fj < N) ret.emplace_back(fi, fj);
int dfs(int at, int par, F& f) { int next = add_var();
has[fi] = has[fj] = 0;
int me = num[at] = ++Time, e, y, top = me; either(cur, ∼li[i]);
rep(sw,0,2) {
trav(pa, ed[at]) if (pa.second != par) { either(cur, next);
ll a = modpow(A[fi][fj], mod-2);
tie(y, e) = pa; either(∼li[i], next);
rep(i,0,M) if (has[i] && A[i][fj]) {
if (num[y]) { cur = ∼next;
ll b = A[i][fj] * a % mod;
top = min(top, num[y]); }
rep(j,0,M) A[i][j] = (A[i][j] - A[fi][j] * b) % mod;
if (num[y] < me) either(cur, ∼li[1]);
}
st.push_back(e); }
swap(fi,fj);
} else {
}
int si = sz(st); vi val, comp, z; int time = 0;
}
int up = dfs(y, e, f); int dfs(int i) {
return ret;
top = min(top, up); int low = val[i] = ++time, x; z.push_back(i);
}
if (up == me) { trav(e, gr[i]) if (!comp[e])
st.push_back(e); low = min(low, val[e] ?: dfs(e));
f(vi(st.begin() + si, st.end())); if (low == val[i]) do {
7.5 DFS algorithms st.resize(si); x = z.back(); z.pop_back();
} comp[x] = low;
SCC.h else if (up < me) st.push_back(e); if (values[x>>1] == -1)
Description: Finds strongly connected components in a directed graph. If else { /∗ e i s a bridge ∗/ } values[x>>1] = x&1;
vertices u, v belong to the same component, we can reach u from v and vice } } while (x != i);
versa. } return val[i] = low;
Usage: scc(graph, [&](vi& v) { ... }) visits all components return top; }
in reverse topological order. comp[i] holds the component }
index of a node (a component only has edges to components with bool solve() {
lower index). ncomps will contain the number of components. template<class F> values.assign(N, -1);
Time: O (E + V ) void bicomps(F f) { val.assign(2*N, 0); comp = val;
bb2963, 24 lines
num.assign(sz(ed), 0); rep(i,0,2*N) if (!comp[i]) dfs(i);
vi val, comp, z, cont; rep(i,0,sz(ed)) if (!num[i]) dfs(i, -1, f); rep(i,0,N) if (comp[2*i] == comp[2*i+1]) return 0;
int Time, ncomps; } return 1;
template<class G, class F> int dfs(int j, G& g, F& f) { }
int low = val[j] = ++Time, x; z.push_back(j); };
trav(e,g[j]) if (comp[e] < 0) 2sat.h
low = min(low, val[e] ?: dfs(e,g,f)); Description: Calculates a valid assignment to boolean variables a,
b, c,... to a 2-SAT problem, so that an expression of the type
if (low == val[j]) { (akkb)&&(!akkc)&&(dkk!b)&&... becomes true, or reports that it is unsatis-
7.6 Heuristics
do { fiable. Negated variables are represented by bit-inversions (∼x).
x = z.back(); z.pop_back(); Usage: TwoSat ts(number of boolean variables); MaximalCliques.h
comp[x] = ncomps; ts.either(0, ∼3); // Var 0 is true or var 3 is false Description: Runs a callback for all maximal cliques in a graph (given as
cont.push_back(x); ts.set value(2); // Var 2 is true a symmetric bitset matrix; self-edges not allowed). Callback is given a bit-
} while (x != j); ts.at most one({0,∼1,2}); // <= 1 of vars 0, ∼1 and 2 are true set representing the maximal clique. Possible optimization: on the top-most
f(cont); cont.clear(); ts.solve(); // Returns true iff it is solvable recursion level, ignore ’cands’, and go through nodes in order of increasing
ncomps++; ts.values[0..N-1] holds the assigned values to the vars degree, where degrees go down as nodes are removed.
KTH MaximumIndependentSet TreePower LCA CompressTree HLD 15
 
Time: O 3n/3 , much faster for sparse graphs vector<ll> dist; Usage: HLD hld(G);
b0d5b1, 12 lines
RMQ<pii> rmq; hld.update(index, value);
typedef bitset<128> B; tie(value, lca) = hld.query(n1, n2);
template<class F> LCA(graph& C) : time(sz(C), -99), dist(sz(C)), rmq(dfs(C)) {} "../data-structures/SegmentTree.h" d952a9, 93 lines
void cliques(vector<B>& eds, F f, B P = ∼B(), B X={}, B R={}) {
typedef vector<pii> vpi;
if (!P.any()) { if (!X.any()) f(R); return; } vpi dfs(graph& C) {
auto q = (P | X)._Find_first(); vector<tuple<int, int, int, ll>> q(1); struct Node {
auto cands = P & ∼eds[q]; vpi ret; int d, par, val, chain = -1, pos = -1;
rep(i,0,sz(eds)) if (cands[i]) { int T = 0, v, p, d; ll di; };
R[i] = 1; while (!q.empty()) {
cliques(eds, f, P & eds[i], X & eds[i], R); tie(v, p, d, di) = q.back(); struct Chain {
R[i] = P[i] = 0; X[i] = 1; q.pop_back(); int par, val;
} if (d) ret.emplace_back(d, p); vector<int> nodes;
} time[v] = T++; Tree tree;
dist[v] = di; };
MaximumIndependentSet.h trav(e, C[v]) if (e.first != p)
Description: To obtain a maximum independent set of a graph, find a max q.emplace_back(e.first, v, d+1, di + e.second); struct HLD {
clique of the complement. If the graph is bipartite, see MinimumVertexCover. } typedef int T;
return ret; const T LOW = -(1<<29);
} void f(T& a, T b) { a = max(a, b); }

7.7 Trees int query(int a, int b) {


if (a == b) return a;
vector<Node> V;
vector<Chain> C;
a = time[a], b = time[b];
TreePower.h return rmq.query(min(a, b), max(a, b)).second; HLD(vector<vpi>& g) : V(sz(g)) {
Description: Calculate power of two jumps in a tree, to support fast upward } dfs(0, -1, g, 0);
jumps and LCAs. Assumes the root node points to itself. ll distance(int a, int b) { trav(c, C) {
Time: construction O (N log N ), queries O (log N ) bfce85, 25 lines
int lca = query(a, b); c.tree = {sz(c.nodes), 0};
return dist[a] + dist[b] - 2 * dist[lca]; for (int ni : c.nodes)
vector<vi> treeJump(vi& P){ }
int on = 1, d = 1; c.tree.update(V[ni].pos, V[ni].val);
}; }
while(on < sz(P)) on *= 2, d++;
vector<vi> jmp(d, P); }
rep(i,1,d) rep(j,0,sz(P))
jmp[i][j] = jmp[i-1][jmp[i-1][j]]; void update(int node, T val) {
return jmp;
CompressTree.h Node& n = V[node]; n.val = val;
Description: Given a rooted tree and a subset S of nodes, compute the if (n.chain != -1) C[n.chain].tree.update(n.pos, val);
}
minimal subtree that contains all the nodes by adding all (at most |S| − 1) }
pairwise LCA’s and compressing edges. Returns a list of (par, orig index)
int jmp(vector<vi>& tbl, int nod, int steps){
representing a tree rooted at 0. The root points to itself. int pard(Node& nod) {
rep(i,0,sz(tbl))
Time: O (|S| log |S|) if (nod.par == -1) return -1;
if(steps&(1<<i)) nod = tbl[i][nod];
"LCA.h" dabd75, 20 lines return V[nod.chain == -1 ? nod.par : C[nod.chain].par].d;
return nod;
} vpi compressTree(LCA& lca, const vi& subset) { }
static vi rev; rev.resize(sz(lca.dist));
int lca(vector<vi>& tbl, vi& depth, int a, int b) { vi li = subset, &T = lca.time; // query a l l ∗edges∗ between n1, n2
if (depth[a] < depth[b]) swap(a, b); auto cmp = [&](int a, int b) { return T[a] < T[b]; }; pair<T, int> query(int i1, int i2) {
a = jmp(tbl, a, depth[a] - depth[b]); sort(all(li), cmp); T ans = LOW;
if (a == b) return a; int m = sz(li)-1; while(i1 != i2) {
for (int i = sz(tbl); i--;) { rep(i,0,m) { Node n1 = V[i1], n2 = V[i2];
int c = tbl[i][a], d = tbl[i][b]; int a = li[i], b = li[i+1]; if (n1.chain != -1 && n1.chain == n2.chain) {
if (c != d) a = c, b = d; li.push_back(lca.query(a, b)); int lo = n1.pos, hi = n2.pos;
} } if (lo > hi) swap(lo, hi);
return tbl[0][a]; sort(all(li), cmp); f(ans, C[n1.chain].tree.query(lo, hi));
} li.erase(unique(all(li)), li.end()); i1 = i2 = C[n1.chain].nodes[hi];
rep(i,0,sz(li)) rev[li[i]] = i; } else {
vpi ret = {pii(0, li[0])}; if (pard(n1) < pard(n2))
LCA.h rep(i,0,sz(li)-1) { n1 = n2, swap(i1, i2);
Description: Data structure for computing lowest common ancestors in a int a = li[i], b = li[i+1]; if (n1.chain == -1)
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.val), i1 = n1.par;
or undirected. Can also find the distance between two nodes. } else {
Usage: LCA lca(undirGraph); return ret; Chain& c = C[n1.chain];
lca.query(firstNode, secondNode); } f(ans, n1.pos ? c.tree.query(n1.pos, sz(c.nodes))
lca.distance(firstNode, secondNode); : c.tree.s[1]);
Time: O (N log N + Q) i1 = c.par;
"../data-structures/RMQ.h" aa0d4d, 37 lines }
typedef vector<pii> vpi; HLD.h }
typedef vector<vpi> graph; Description: Decomposes a tree into vertex disjoint heavy paths and light }
edges such that the path from any leaf to the root contains at most log(n) return make_pair(ans, i1);
struct LCA { light edges. The function of the HLD can be changed by modifying T, LOW }
vi time; and f. f is assumed to be associative and commutative.
KTH LinkCutTree DirectedMST MatrixTree 16
// query a l l ∗nodes∗ between n1, n2 int c1 = up(), c2 = p->up(); void prop() {
pair<T, int> query2(int i1, int i2) { if (c2 == -1) p->rot(c1, 2); key.w += delta;
pair<T, int> ans = query(i1, i2); else p->p->rot(c2, c1 != c2); if (l) l->delta += delta;
f(ans.first, V[ans.second].val); } if (r) r->delta += delta;
return ans; } delta = 0;
} Node* first() { }
push_flip(); Edge top() { prop(); return key; }
pii dfs(int at, int par, vector<vpi>& g, int d) { return c[0] ? c[0]->first() : (splay(), this); };
V[at].d = d; V[at].par = par; } Node *merge(Node *a, Node *b) {
int sum = 1, ch, nod, sz; }; if (!a || !b) return a ?: b;
tuple<int,int,int> mx(-1,-1,-1); a->prop(), b->prop();
trav(e, g[at]){ struct LinkCut { if (a->key.w > b->key.w) swap(a, b);
if (e.first == par) continue; vector<Node> node; swap(a->l, (a->r = merge(b, a->r)));
tie(sz, ch) = dfs(e.first, at, g, d+1); LinkCut(int N) : node(N) {} return a;
V[e.first].val = e.second; }
sum += sz; void link(int u, int v) { // add an edge (u, v) void pop(Node*& a) { a->prop(); a = merge(a->l, a->r); }
mx = max(mx, make_tuple(sz, e.first, ch)); assert(!connected(u, v));
} make_root(&node[u]); ll dmst(int n, int r, vector<Edge>& g) {
tie(sz, nod, ch) = mx; node[u].pp = &node[v]; UF uf(n);
if (2*sz < sum) return pii(sum, -1); } vector<Node*> heap(n);
if (ch == -1) { ch = sz(C); C.emplace_back(); } void cut(int u, int v) { // remove an edge (u, v) trav(e, g) heap[e.b] = merge(heap[e.b], new Node{e});
V[nod].pos = sz(C[ch].nodes); Node *x = &node[u], *top = &node[v]; ll res = 0;
V[nod].chain = ch; make_root(top); x->splay(); vi seen(n, -1), path(n);
C[ch].par = at; assert(top == (x->pp ?: x->c[0])); seen[r] = r;
C[ch].nodes.push_back(nod); if (x->pp) x->pp = 0; rep(s,0,n) {
return pii(sum, ch); else { int u = s, qi = 0, w;
} x->c[0] = top->p = 0; while (seen[u] < 0) {
}; x->fix(); path[qi++] = u, seen[u] = s;
} if (!heap[u]) return -1;
} Edge e = heap[u]->top();
LinkCutTree.h bool connected(int u, int v) { // are u, v in the same tree? heap[u]->delta -= e.w, pop(heap[u]);
Description: Represents a forest of unrooted trees. You can add and re- Node* nu = access(&node[u])->first(); res += e.w, u = uf.find(e.a);
move edges (as long as the result is still a forest), and check whether two return nu == access(&node[v])->first(); if (seen[u] == s) {
nodes are in the same tree. } Node* cyc = 0;
Time: All operations take amortized O (log N ). 693483, 90 lines void make_root(Node* u) { do cyc = merge(cyc, heap[w = path[--qi]]);
access(u); while (uf.join(u, w));
struct Node { // Splay tree . Root ’ s pp contains tree ’ s parent .
u->splay(); u = uf.find(u);
Node *p = 0, *pp = 0, *c[2];
if(u->c[0]) { heap[u] = cyc, seen[u] = -1;
bool flip = 0;
u->c[0]->p = 0; }
Node() { c[0] = c[1] = 0; fix(); }
u->c[0]->flip ˆ= 1; }
void fix() {
u->c[0]->pp = u; }
if (c[0]) c[0]->p = this;
u->c[0] = 0; return res;
if (c[1]) c[1]->p = this;
u->fix(); }
// (+ update sum of subtree elements etc . i f wanted)
}
}
}
void push_flip() {
Node* access(Node* u) {
MatrixTree.h
if (!flip) return; Description: To count the number of spanning trees in an undirected
u->splay();
flip = 0; swap(c[0], c[1]); graph G: create an N × N matrix mat, and for each edge (a, b) ∈ G, do
while (Node* pp = u->pp) {
if (c[0]) c[0]->flip ˆ= 1; mat[a][a]++, mat[b][b]++, mat[a][b]--, mat[b][a]--. Remove the
pp->splay(); u->pp = 0;
if (c[1]) c[1]->flip ˆ= 1; last row and column, and take the determinant.
if (pp->c[1]) {
}
pp->c[1]->p = 0; pp->c[1]->pp = pp; }
int up() { return p ? p->c[1] == this : -1; }
pp->c[1] = u; pp->fix(); u = pp;
void rot(int i, int b) {
}
int h = i ˆ b;
return u;
Node *x = c[i], *y = b == 2 ? x : x->c[h], *z = b ? y : x;
}
if ((y->p = p)) p->c[up()] = y;
};
c[i] = z->c[i ˆ 1];
if (b < 2) {
x->c[h] = y->c[h ˆ 1];
z->c[h ˆ 1] = b ? x : this; DirectedMST.h
} Description: Edmonds’ algorithm for finding the weight of the minimum
y->c[i ˆ 1] = b ? this : x; spanning tree/arborescence of a directed graph, given a root node. If no
fix(); x->fix(); y->fix(); MST exists, returns -1.
if (p) p->fix(); Time: O (E log V )
swap(pp, y->pp); "../data-structures/UnionFind.h" a69883, 48 lines
} struct Edge { int a, b; ll w; };
void splay() { struct Node {
for (push_flip(); p; ) { Edge key;
if (p->p) p->p->push_flip(); Node *l, *r;
p->push_flip(); push_flip(); ll delta;
KTH Point lineDistance SegmentDistance SegmentIntersection lineIntersection sideOf onSegment linearTransformation Angle 17
Geometry (8) SegmentIntersection.h
Description:
onSegment.h
Description: Returns true iff p lies on the line segment from s to e. Use
If a unique intersection point between the line segments going (segDist(s,e,p)<=epsilon) instead when using Point<double>.
from s1 to e1 and from s2 to e2 exists then it is returned. "Point.h" c597e8, 3 lines
8.1 Geometric primitives If no intersection point exists an empty vector is returned. e1 template<class P> bool onSegment(P s, P e, P p) {
If infinitely many exist a vector with 2 elements is returned,
containing the endpoints of the common line segment. The e2
return p.cross(s, e) == 0 && (s - p).dot(e - p) <= 0;
wrong position will be returned if P is Point<ll> and the in- r1 }
Point.h s1 s2
Description: Class to handle points in the plane. T can be e.g. double or tersection point does not have integer coordinates. Products
long long. (Avoid int.) of three coordinates are used in intermediate steps so watch
4d90b5, 26 lines
out for overflow if using int or long long. r p1
template <class T> int sgn(T x) { return (x > 0) - (x < 0); } Usage: vector<P> inter = segInter(s1,e1,s2,e2);
linearTransformation.h
Description:
template<class T> if (sz(inter)==1) p0 res
struct Point { cout << "segments intersect at " << inter[0] << endl; Apply the linear transformation (translation, rotation and q0
typedef Point P; "Point.h", "onSegment.h" 9d57f2, 13 lines scaling) which takes line p0-p1 to line q0-q1 to point r. q1
T x, y; template<class P> vector<P> segInter(P a, P b, P c, P d) { "Point.h" 03a306, 6 lines
explicit Point(T x=0, T y=0) : x(x), y(y) {} auto oa = c.cross(d, a), ob = c.cross(d, b), typedef Point<double> P;
bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); } oc = a.cross(b, c), od = a.cross(b, d); P linearTransformation(const P& p0, const P& p1,
bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); } // Checks i f intersection i s single non−endpoint point . const P& q0, const P& q1, const P& r) {
P operator+(P p) const { return P(x+p.x, y+p.y); } if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn(od) < 0) P dp = p1-p0, dq = q1-q0, num(dp.cross(dq), dp.dot(dq));
P operator-(P p) const { return P(x-p.x, y-p.y); } return {(a * ob - b * oa) / (ob - oa)}; return q0 + P((r-p0).cross(num), (r-p0).dot(num))/dp.dist2();
P operator*(T d) const { return P(x*d, y*d); } set<P> s; }
P operator/(T d) const { return P(x/d, y/d); } if (onSegment(c, d, a)) s.insert(a);
T dot(P p) const { return x*p.x + y*p.y; } if (onSegment(c, d, b)) s.insert(b);
T cross(P p) const { return x*p.y - y*p.x; } if (onSegment(a, b, c)) s.insert(c);
T cross(P a, P b) const { return (a-*this).cross(b-*this); }
T dist2() const { return x*x + y*y; }
if (onSegment(a, b, d)) s.insert(d); Angle.h
return {all(s)}; Description: A class for ordering angles (as represented by int points and
double dist() const { return sqrt((double)dist2()); } } a number of rotations around the origin). Useful for rotational sweeping.
// angle to x−axis in interval [−pi , pi ]
Sometimes also represents points or vectors.
double angle() const { return atan2(y, x); }
lineIntersection.h Usage: vector<Angle> v = {w[0], w[0].t360() ...}; // sorted
P unit() const { return *this/dist(); } // makes d i s t ()=1
Description: int j = 0; rep(i,0,n) { while (v[j] < v[i].t180()) ++j; }
P perp() const { return P(-y, x); } // rotates +90 degrees
If a unique intersection point of the lines going through s1,e1 // sweeps j such that (j-i) represents the number of positively
P normal() const { return perp().unit(); }
and s2,e2 exists {1, point} is returned. If no intersection point oriented triangles with vertices at 0 and i 0f0602, 35 lines
// returns point rotated ’a ’ radians ccw around the origin
P rotate(double a) const { exists {0, (0,0)} is returned and if infinitely many exists {-1, e2 r struct Angle {
return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); } (0,0)} is returned. The wrong position will be returned if P
}; is Point<ll> and the intersection point does not have inte- e1 s2 int x, y;
int t;
ger coordinates. Products of three coordinates are used in s1 Angle(int x, int y, int t=0) : x(x), y(y), t(t) {}
intermediate steps so watch out for overflow if using int or ll. Angle operator-(Angle b) const { return {x-b.x, y-b.y, t}; }
Usage: auto res = lineInter(s1,e1,s2,e2);
int half() const {
lineDistance.h if (res.first == 1)
assert(x || y);
Description: cout << "intersection point at " << res.second << endl;
Returns the signed distance between point p and the line con- return y < 0 || (y == 0 && x < 0);
"Point.h" a01f81, 8 lines
taining points a and b. Positive value on left side and negative res template<class P>
}
Angle t90() const { return {-y, x, t + (half() && x >= 0)}; }
on right as seen from a towards b. a==b gives nan. P is sup- e p pair<int, P> lineInter(P s1, P e1, P s2, P e2) { Angle t180() const { return {-x, -y, t + half()}; }
posed to be Point<T> or Point3D<T> where T is e.g. double auto d = (e1 - s1).cross(e2 - s2);
or long long. It uses products in intermediate steps so watch Angle t360() const { return {x, y, t + 1}; }
if (d == 0) // i f p a r a l l e l };
out for overflow if using int or long long. Using Point3D will s return {-(s1.cross(e1, s2) == 0), P(0, 0)};
always give a non-negative distance. bool operator<(Angle a, Angle b) {
"Point.h" f6bf6b, 4 lines
auto p = s2.cross(e1, e2), q = s2.cross(e2, s1); // add a . dist2 () and b . dist2 () to also compare distances
return {1, (s1 * p + e1 * q) / d}; return make_tuple(a.t, a.half(), a.y * (ll)b.x) <
template<class P> }
double lineDist(const P& a, const P& b, const P& p) { make_tuple(b.t, b.half(), a.x * (ll)b.y);
return (double)(b-a).cross(p-a)/(b-a).dist(); }
} sideOf.h
Description: Returns where p is as seen from s towards e. 1/0/-1 ⇔ left/on // Given two points , t h i s calculates the smallest angle between
line/right. If the optional argument eps is given 0 is returned if p is within // them, i . e . , the angle that covers the defined l i n e segment .

e res p
distance eps from the line. P is supposed to be Point<T> where T is e.g. pair<Angle, Angle> segmentAngles(Angle a, Angle b) {
SegmentDistance.h double or long long. It uses products in intermediate steps so watch out for if (b < a) swap(a, b);
Description: overflow if using int or long long. return (b < a.t180() ?
Returns the shortest distance between point p and the line make_pair(a, b) : make_pair(b, a.t360()));
Usage: bool left = sideOf(p1,p2,q)==1;
segment from point s to e. s }
"Point.h" 3af81c, 9 lines
Usage: Point<double> a, b(2,2), p(1,1); Angle operator+(Angle a, Angle b) { // point a + vector b
bool onSegment = segDist(a,b,p) < 1e-10; template<class P>
Angle r(a.x + b.x, a.y + b.y, a.t);
"Point.h" 5c88f4, 6 lines int sideOf(P s, P e, P p) { return sgn(s.cross(e, p)); }
if (a.t180() < r) r.t--;
typedef Point<double> P; return r.t180() < a ? r.t360() : r;
template<class P>
double segDist(P& s, P& e, P& p) { }
int sideOf(const P& s, const P& e, const P& p, double eps) {
if (s==e) return (p-s).dist(); Angle angleDiff(Angle a, Angle b) { // angle b − angle a
auto a = (e-s).cross(p-s);
auto d = (e-s).dist2(), t = min(d,max(.0,(p-s).dot(e-s))); int tu = b.t - a.t; a.t = b.t;
double l = (e-s).dist()*eps;
return ((p-s)*d-(e-s)*t).dist()/d; return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x, tu - (b < a)};
return (a > l) - (a < -l);
} }
}
KTH CircleIntersection circleTangents circumcircle MinimumEnclosingCircle InsidePolygon PolygonArea PolygonCenter PolygonCut ConvexHull HullDiameter PointInsideHull 18
8.2 Circles rep(k,0,j) if ((o - ps[k]).dist() > r * EPS) { vector<P> res;
o = ccCenter(ps[i], ps[j], ps[k]); rep(i,0,sz(poly)) {
r = (o - ps[i]).dist(); P cur = poly[i], prev = i ? poly[i-1] : poly.back();
CircleIntersection.h } bool side = s.cross(e, cur) < 0;
Description: Computes the pair of points at which two circles intersect. } if (side != (s.cross(e, prev) < 0))
Returns false in case of no intersection. } res.push_back(lineInter(s, e, cur, prev).second);
"Point.h" 84d6d3, 11 lines
return {o, r}; if (side)
typedef Point<double> P; } res.push_back(cur);
bool circleInter(P a,P b,double r1,double r2,pair<P, P>* out) { }
if (a == b) { assert(r1 != r2); return false; } return res;
P vec = b - a;
double d2 = vec.dist2(), sum = r1+r2, dif = r1-r2,
8.3 Polygons }

p = (d2 + r1*r1 - r2*r2)/(d2*2), h2 = r1*r1 - p*p*d2;


if (sum*sum < d2 || dif*dif > d2) return false; InsidePolygon.h ConvexHull.h
P mid = a + vec*p, per = vec.perp() * sqrt(fmax(0, h2) / d2); Description: Returns true if p lies within the polygon. If strict is true, it Description:
*out = {mid + per, mid - per}; returns false for points on the boundary. The algorithm uses products in Returns a vector of indices of the convex hull in counter-
return true; intermediate steps so watch out for overflow. clockwise order. Points on the edge of the hull between two
} Usage: vector<P> v = {P{4,4}, P{1,2}, P{2,1}}; other points are not considered part of the hull.
bool in = inPolygon(v, P{3, 3}, false); Time: O (n log n)
Time: O (n) "Point.h" 26a0a9, 13 lines
circleTangents.h "Point.h", "onSegment.h", "SegmentDistance.h" 2bf504, 11 lines typedef Point<ll> P;
Description: template<class P> vector<P> convexHull(vector<P> pts) {
Returns a pair of the two points on the circle with radius r second bool inPolygon(vector<P> &p, P a, bool strict = true) { if (sz(pts) <= 1) return pts;
centered around c whos tangent lines intersect p. If p lies r int cnt = 0, n = sz(p); sort(all(pts));
within the circle NaN-points are returned. P is intended to c rep(i,0,n) { vector<P> h(sz(pts)+1);
be Point<double>. The first point is the one to the right as
p first P q = p[(i + 1) % n]; int s = 0, t = 0;
seen from the p towards c. if (onSegment(p[i], q, a)) return !strict; for (int it = 2; it--; s = --t, reverse(all(pts)))
Usage: typedef Point<double> P; //or : i f ( segDist (p [ i ] , q , a) <= eps) return ! s t r i c t ; trav(p, pts) {
pair<P,P> p = circleTangents(P(100,2),P(0,0),2); cnt ˆ= ((a.y<p[i].y) - (a.y<q.y)) * a.cross(p[i], q) > 0; while (t >= s + 2 && h[t-2].cross(h[t-1], p) <= 0) t--;
"Point.h" b70bc5, 6 lines } h[t++] = p;
template<class P> return cnt; }
pair<P,P> circleTangents(const P &p, const P &c, double r) { } return {h.begin(), h.begin() + t - (t == 2 && h[0] == h[1])};
P a = p-c; }
double x = r*r/a.dist2(), y = sqrt(x-x*x); PolygonArea.h
return make_pair(c+a*x+a.perp()*y, c+a*x-a.perp()*y);
}
Description: Returns twice the signed area of a polygon. Clockwise enu- HullDiameter.h
meration gives negative area. Watch out for overflow if using int as T! Description: Returns the two points with max distance on a convex hull
"Point.h" f12300, 6 lines (ccw, no duplicate/colinear points). c571b8, 12 lines
circumcircle.h template<class T>
typedef Point<ll> P;
Description: T polygonArea2(vector<Point<T>>& v) {
The circumcirle of a triangle is the circle intersecting all B T a = v.back().cross(v[0]); array<P, 2> hullDiameter(vector<P> S) {
int n = sz(S), j = n < 2 ? 0 : 1;
three vertices. ccRadius returns the radius of the circle going r c rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]);
pair<ll, array<P, 2>> res({0, {S[0], S[0]}});
through points A, B and C and ccCenter returns the center C return a;
rep(i,0,j)
of the same circle. A }
for (;; j = (j + 1) % n) {
"Point.h" 1caa3a, 9 lines res = max(res, {(S[i] - S[j]).dist2(), {S[i], S[j]}});
typedef Point<double> P; PolygonCenter.h if ((S[(j + 1) % n] - S[j]).cross(S[i + 1] - S[i]) >= 0)
double ccRadius(const P& A, const P& B, const P& C) { Description: Returns the center of mass for a polygon. break;
return (B-A).dist()*(C-B).dist()*(A-C).dist()/ Time: O (n) }
abs((B-A).cross(C-A))/2; "Point.h" 9706dc, 9 lines return res.second;
} typedef Point<double> P; }
P ccCenter(const P& A, const P& B, const P& C) { P polygonCenter(const vector<P>& v) {
P b = C-A, c = B-A; P res(0, 0); double A = 0;
return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2; for (int i = 0, j = sz(v) - 1; i < sz(v); j = i++) { PointInsideHull.h
} res = res + (v[i] + v[j]) * v[j].cross(v[i]); Description: Determine whether a point t lies inside a convex hull (CCW
A += v[j].cross(v[i]); order, with no colinear points). Returns true if point lies within the hull. If
} strict is true, points on the boundary aren’t included.
MinimumEnclosingCircle.h return res / A / 3; Time: O (log N )
Description: Computes the minimum circle that encloses a set of points. } "Point.h", "sideOf.h", "onSegment.h" 71446b, 14 lines
Time: expected O (n) typedef Point<ll> P;
"circumcircle.h" 09dd0a, 17 lines

pair<P, double> mec(vector<P> ps) { PolygonCut.h e bool inHull(const vector<P>& l, P p, bool strict = true) {
shuffle(all(ps), mt19937(time(0))); Description: int a = 1, b = sz(l) - 1, r = !strict;
P o = ps[0]; Returns a vector with the vertices of a polygon with every- if (sz(l) < 3) return r && onSegment(l[0], l.back(), p);
double r = 0, EPS = 1 + 1e-8; thing to the left of the line going from s to e cut away. if (sideOf(l[0], l[a], l[b]) > 0) swap(a, b);
rep(i,0,sz(ps)) if ((o - ps[i]).dist() > r * EPS) { Usage: vector<P> p = ...; s if (sideOf(l[0], l[a], p) >= r || sideOf(l[0], l[b], p)<= -r)
o = ps[i], r = 0; p = polygonCut(p, P(0,0), P(1,0)); return false;
rep(j,0,i) if ((o - ps[j]).dist() > r * EPS) { "Point.h", "lineIntersection.h" f2b7d4, 13 lines while (abs(a - b) > 1) {
o = (ps[i] + ps[j]) / 2; typedef Point<double> P; int c = (a + b) / 2;
r = (o - ps[i]).dist(); vector<P> polygonCut(const vector<P>& poly, P s, P e) { (sideOf(l[0], l[c], p) > 0 ? b : a) = c;
KTH LineHullIntersection ClosestPair kdTree FastDelaunay 19
} int j = 0; if (bsec < best.first)
return sgn(l[a].cross(l[b], p)) < r; trav(p, v) { best = min(best, search(s, p));
} P d{1 + (ll)sqrt(ret.first), 0}; return best;
while (v[j].y <= p.y - d.x) S.erase(v[j++]); }
auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d);
LineHullIntersection.h for (; lo != hi; ++lo) // find nearest point to a point , and i t s squared distance
Description: Line-convex polygon intersection. The polygon must be ccw
ret = min(ret, {(*lo - p).dist2(), {*lo, p}}); // ( requires an arbitrary operator< for Point)
and have no colinear points. lineHull(line, poly) returns a pair describing the
S.insert(p); pair<T, P> nearest(const P& p) {
intersection of a line with the polygon: • (−1, −1) if no collision, • (i, −1) if
} return search(root, p);
touching the corner i, • (i, i) if along side (i, i + 1), • (i, j) if crossing sides
return ret.second; }
(i, i + 1) and (j, j + 1). In the last case, if a corner i is crossed, this is treated
} };
as happening on side (i, i + 1). The points are returned in the same order as
the line hits the polygon. extrVertex returns the point of a hull with the
max projection onto a line.
Time: O (N + Q log n) kdTree.h FastDelaunay.h
"Point.h" 758f22, 39 lines Description: KD-tree (2d, can be extended to 3d) Description: Fast Delaunay triangulation. Each circumcircle contains none
"Point.h" bac5b0, 63 lines of the input points. There must be no duplicate points. If all points are on a
typedef array<P, 2> Line;
typedef long long T; line, no triangles will be returned. Should work for doubles as well, though
#define cmp(i,j) sgn(dir.perp().cross(poly[(i)%n]-poly[(j)%n]))
typedef Point<T> P; there may be precision issues in ’circ’. Returns triangles in order {t[0][0],
#define extr(i) cmp(i + 1, i) >= 0 && cmp(i, i - 1 + n) < 0
const T INF = numeric_limits<T>::max(); t[0][1], t[0][2], t[1][0], . . . }, all counter-clockwise.
int extrVertex(vector<P>& poly, P dir) {
Time: O (n log n)
int n = sz(poly), lo = 0, hi = n;
bool on_x(const P& a, const P& b) { return a.x < b.x; } "Point.h" bf87ec, 88 lines
if (extr(0)) return 0;
while (lo + 1 < hi) { bool on_y(const P& a, const P& b) { return a.y < b.y; } typedef Point<ll> P;
int m = (lo + hi) / 2; typedef struct Quad* Q;
if (extr(m)) return m; struct Node { typedef __int128_t lll; // (can be l l i f coords are < 2e4)
int ls = cmp(lo + 1, lo), ms = cmp(m + 1, m); P pt; // i f t h i s i s a leaf , the single point in i t P arb(LLONG_MAX,LLONG_MAX); // not equal to any other point
(ls < ms || (ls == ms && ls == cmp(lo, m)) ? hi : lo) = m; T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; // bounds
} Node *first = 0, *second = 0; struct Quad {
return lo; bool mark; Q o, rot; P p;
} T distance(const P& p) { // min squared distance to a point P F() { return r()->p; }
T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x); Q r() { return rot->rot; }
#define cmpL(i) sgn(line[0].cross(poly[i], line[1])) T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y); Q prev() { return rot->o->rot; }
array<int, 2> lineHull(Line line, vector<P> poly) { return (P(x,y) - p).dist2(); Q next() { return r()->prev(); }
int endA = extrVertex(poly, (line[0] - line[1]).perp()); } };
int endB = extrVertex(poly, (line[1] - line[0]).perp());
if (cmpL(endA) < 0 || cmpL(endB) > 0) Node(vector<P>&& vp) : pt(vp[0]) { bool circ(P p, P a, P b, P c) { // i s p in the circumcircle?
return {-1, -1}; for (P p : vp) { lll p2 = p.dist2(), A = a.dist2()-p2,
array<int, 2> res; x0 = min(x0, p.x); x1 = max(x1, p.x); B = b.dist2()-p2, C = c.dist2()-p2;
rep(i,0,2) { y0 = min(y0, p.y); y1 = max(y1, p.y); return p.cross(a,b)*C + p.cross(b,c)*A + p.cross(c,a)*B > 0;
int lo = endB, hi = endA, n = sz(poly); } }
while ((lo + 1) % n != hi) { if (vp.size() > 1) { Q makeEdge(P orig, P dest) {
int m = ((lo + hi + (lo < hi ? 0 : n)) / 2) % n; // s p l i t on x i f the box i s wider than high (not best Q q[] = {new Quad{0,0,0,orig}, new Quad{0,0,0,arb},
(cmpL(m) == cmpL(endB) ? lo : hi) = m; heuristic . . . ) new Quad{0,0,0,dest}, new Quad{0,0,0,arb}};
} sort(all(vp), x1 - x0 >= y1 - y0 ? on_x : on_y); rep(i,0,4)
res[i] = (lo + !cmpL(hi)) % n; // divide by taking h a l f the array for each child (not q[i]->o = q[-i & 3], q[i]->rot = q[(i+1) & 3];
swap(endA, endB); // best performance with many duplicates in the middle) return *q;
} int half = sz(vp)/2; }
if (res[0] == res[1]) return {res[0], -1}; first = new Node({vp.begin(), vp.begin() + half}); void splice(Q a, Q b) {
if (!cmpL(res[0]) && !cmpL(res[1])) second = new Node({vp.begin() + half, vp.end()}); swap(a->o->rot->o, b->o->rot->o); swap(a->o, b->o);
switch ((res[0] - res[1] + sz(poly) + 1) % sz(poly)) { } }
case 0: return {res[0], res[0]}; } Q connect(Q a, Q b) {
case 2: return {res[1], res[1]}; }; Q q = makeEdge(a->F(), b->p);
} splice(q, a->next());
return res; struct KDTree { splice(q->r(), b);
} Node* root; return q;
KDTree(const vector<P>& vp) : root(new Node({all(vp)})) {} }

8.4 Misc. Point Set Problems pair<T, P> search(Node *node, const P& p) {
if (!node->first) {
pair<Q,Q> rec(const vector<P>& s) {
if (sz(s) <= 3) {
// uncomment i f we should not find the point i t s e l f : Q a = makeEdge(s[0], s[1]), b = makeEdge(s[1], s.back());
ClosestPair.h // i f (p == node−>pt ) return {INF, P() }; if (sz(s) == 2) return { a, a->r() };
Description: Finds the closest pair of points. return make_pair((p - node->pt).dist2(), node->pt); splice(a->r(), b);
Time: O (n log n) } auto side = s[0].cross(s[1], s[2]);
"Point.h" d31bbf, 17 lines Q c = side ? connect(b, a) : 0;
typedef Point<ll> P; Node *f = node->first, *s = node->second; return {side < 0 ? c->r() : a, side < 0 ? c : b->r() };
pair<P, P> closest(vector<P> v) { T bfirst = f->distance(p), bsec = s->distance(p); }
assert(sz(v) > 1); if (bfirst > bsec) swap(bsec, bfirst), swap(f, s);
set<P> S; #define H(e) e->F(), e->p
sort(all(v), [](P a, P b) { return a.y < b.y; }); // search c l o s e s t side f i r s t , other side i f needed #define valid(e) (e->F().cross(H(base)) > 0)
pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P()}}; auto best = search(f, p); Q A, B, ra, rb;
KTH PolyhedronVolume Point3D 3dHull sphericalDistance KMP Zfunc 20
int half = sz(s) / 2; P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); } rep(j,0,nw) {
tie(ra, A) = rec({all(s) - half}); P operator*(T d) const { return P(x*d, y*d, z*d); } F f = FS[j];
tie(B, rb) = rec({sz(s) - half + all(s)}); 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);
while ((B->p.cross(H(A)) < 0 && (A = A->next())) || T dot(R p) const { return x*p.x + y*p.y + z*p.z; } C(a, b, c); C(a, c, b); C(b, c, a);
(A->p.cross(H(B)) > 0 && (B = B->r()->o))); P cross(R p) const { }
Q base = connect(B->r(), A); return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); }
if (A->p == ra->p) ra = base->r(); } trav(it, FS) if ((A[it.b] - A[it.a]).cross(
if (B->p == rb->p) rb = base; T dist2() const { return x*x + y*y + z*z; } A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b);
double dist() const { return sqrt((double)dist2()); } return FS;
#define DEL(e, init, dir) Q e = init->dir; if (valid(e)) \ //Azimuthal angle ( longitude ) to x−axis in interval [−pi , pi ] };
while (circ(e->dir->F(), H(base), e->F())) { \ double phi() const { return atan2(y, x); }
Q t = e->dir; \ //Zenith angle ( l a t i t u d e ) to the z−axis in interval [0 , pi ]
splice(e, e->prev()); \ double theta() const { return atan2(sqrt(x*x+y*y),z); }
sphericalDistance.h
Description: Returns the shortest distance on the sphere with radius ra-
splice(e->r(), e->r()->prev()); \ 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 )
e = t; \ //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-
for (;;) { //returns point rotated ’ angle ’ radians ccw around axis
cal coordinates to cartesian coordinates so if that is what you have you can
DEL(LC, base->r(), o); DEL(RC, base, prev()); P rotate(double angle, P axis) const {
use only the two last rows. dx*radius is then the difference between the
if (!valid(LC) && !valid(RC)) break; 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
if (!valid(LC) || (valid(RC) && circ(H(RC), H(LC)))) return u*dot(u)*(1-c) + (*this)*c - cross(u)*s;
points.
base = connect(RC, base->r()); } 611f07, 8 lines
else }; double sphericalDistance(double f1, double t1,
base = connect(base->r(), LC->r()); double f2, double t2, double radius) {
} double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1);
return { ra, rb }; 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);
vector<P> triangulate(vector<P> pts) { faces will point return radius*2*asin(d/2);
 outwards.
sort(all(pts)); assert(unique(all(pts)) == pts.end()); Time: O n2 }
if (sz(pts) < 2) return {}; "Point3D.h" c172e9, 49 lines
Q e = rec(pts).first;
typedef Point3D<double> P3;
vector<Q> q = {e};
int qi = 0;
Strings (9)
struct PR {
while (e->o->F().cross(e->F(), e->p) < 0) e = e->o;
#define ADD { Q c = e; do { c->mark = 1; pts.push_back(c->p); \
void ins(int x) { (a == -1 ? a : b) = x; } KMP.h
void rem(int x) { (a == x ? a : b) = -1; } Description: pi[x] computes the length of the longest prefix of s that ends
q.push_back(c->r()); c = c->next(); } while (c != e); }
int cnt() { return (a != -1) + (b != -1); } at x, other than s[0...x] itself (abacaba -> 0010123). Can be used to find all
ADD; pts.clear();
int a, b; occurrences of a string.
while (qi < sz(q)) if (!(e = q[qi++])->mark) ADD;
}; Time: O (n)
return pts; d4375c, 16 lines
} vi pi(const string& s) {
struct F { P3 q; int a, b, c; };
vi p(sz(s));
vector<F> hull3d(const vector<P3>& A) { rep(i,1,sz(s)) {
8.5 3D 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];
PolyhedronVolume.h #define E(x,y) E[f.x][f.y] p[i] = g + (s[i] == s[g]);
Description: Magic formula for the volume of a polyhedron. Faces should vector<F> FS; }
point outwards. auto mf = [&](int i, int j, int k, int l) { return p;
1ec4d3, 6 lines }
P3 q = (A[j] - A[i]).cross((A[k] - A[i]));
template<class V, class L> if (q.dot(A[l]) > q.dot(A[i]))
double signed_poly_volume(const V& p, const L& trilist) { q = q * -1; vi match(const string& s, const string& pat) {
double v = 0; F f{q, i, j, k}; vi p = pi(pat + ’\0’ + s), res;
trav(i, trilist) v += p[i.a].cross(p[i.b]).dot(p[i.c]); E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i); rep(i,sz(p)-sz(s),sz(p))
return v / 6; FS.push_back(f); if (p[i] == sz(pat)) res.push_back(i - 2 * sz(pat));
} }; return res;
rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4) }
Point3D.h mf(i, j, k, 6 - i - j - k);
Description: Class to handle points in 3D space. T can be e.g. double or Zfunc.h
long long. rep(i,4,sz(A)) { Description: z[x] computes the length of the longest common prefix of s[i:]
8058ae, 32 lines rep(j,0,sz(FS)) { and s, except z[0] = 0. (abacaba -> 0010301)
template<class T> struct Point3D { F f = FS[j]; Time: O (n)
typedef Point3D P; if(f.q.dot(A[i]) > f.q.dot(A[f.a])) { 3ae526, 12 lines

typedef const P& R; E(a,b).rem(f.c); vi Z(string S) {


T x, y, z; E(a,c).rem(f.b); vi z(sz(S));
explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {} E(b,c).rem(f.a); int l = -1, r = -1;
bool operator<(R p) const { swap(FS[j--], FS.back()); rep(i,1,sz(S)) {
return tie(x, y, z) < tie(p.x, p.y, p.z); } FS.pop_back(); z[i] = i >= r ? 0 : min(r - i, z[i - l]);
bool operator==(R p) const { } while (i + z[i] < sz(S) && S[i + z[i]] == S[z[i]])
return tie(x, y, z) == tie(p.x, p.y, p.z); } } z[i]++;
P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); } int nw = sz(FS); if (i + z[i] > r)
KTH Manacher MinRotation SuffixArray SuffixTree Hashing AhoCorasick 21
l = i, r = i + z[i]; }; // or work mod 10ˆ9+7 i f the Birthday paradox i s not a problem .
} struct H {
return z; typedef uint64_t ull;
} SuffixTree.h ull x; H(ull x=0) : x(x) {}
Description: Ukkonen’s algorithm for online suffix tree construction. Each #define OP(O,A,B) H operator O(H o) { ull r = x; asm \
node contains indices [l, r) into the string, and a list of child nodes. Suffixes (A "addq %%rdx, %0\n adcq $0,%0" : "+a"(r) : B); return r; }
Manacher.h are given by traversals of this tree, joining [l, r) substrings. The root is 0 (has OP(+,,"d"(o.x)) OP(*,"mul %1\n", "r"(o.x) : "rdx")
Description: For each position in a string, computes p[0][i] = half length l = -1, r = 0), non-existent children are -1. To get a complete tree, append H operator-(H o) { return *this + ∼o.x; }
of longest even palindrome around pos i, p[1][i] = longest odd (half rounded a dummy symbol – otherwise it may contain an incomplete path (still useful ull get() const { return x + !∼x; }
down). for substring matching, though). bool operator==(H o) const { return get() == o.get(); }
Time: O (N ) Time: O (26N )
e7ad79, 13 lines aae0b8, 50 lines bool operator<(H o) const { return get() < o.get(); }
array<vi, 2> manacher(const string& s) { struct SuffixTree { };
int n = sz(s); enum { N = 200010, ALPHA = 26 }; // N ∼ 2∗maxlen+10 static const H C = (ll)1e11+3; // (order ∼ 3e9 ; random also ok)
array<vi,2> p = {vi(n+1), vi(n)}; int toi(char c) { return c - ’a’; }
rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++) { string a; // v = cur node , q = cur position struct HashInterval {
int t = r-i+!z; int t[N][ALPHA],l[N],r[N],p[N],s[N],v=0,q=0,m=2; vector<H> ha, pw;
if (i<r) p[z][i] = min(t, p[z][l+t]); HashInterval(string& str) : ha(sz(str)+1), pw(ha) {
int L = i-p[z][i], R = i+p[z][i]-!z; void ukkadd(int i, int c) { suff: pw[0] = 1;
while (L>=1 && R+1<n && s[L-1] == s[R+1]) if (r[v]<=q) { rep(i,0,sz(str))
p[z][i]++, L--, R++; if (t[v][c]==-1) { t[v][c]=m; l[m]=i; ha[i+1] = ha[i] * C + str[i],
if (R>r) l=L, r=R; p[m++]=v; v=s[v]; q=r[v]; goto suff; } pw[i+1] = pw[i] * C;
} v=t[v][c]; q=l[v]; }
return p; } H hashInterval(int a, int b) { // hash [ a , b)
} if (q==-1 || c==toi(a[q])) q++; else { return ha[b] - ha[a] * pw[b - a];
l[m+1]=i; p[m+1]=m; l[m]=l[v]; r[m]=q; }
p[m]=p[v]; t[m][c]=m+1; t[m][toi(a[q])]=v; };
MinRotation.h l[v]=q; p[v]=m; t[p[m]][toi(a[l[m]])]=m;
Description: Finds the lexicographically smallest rotation of a string. vector<H> getHashes(string& str, int length) {
v=s[p[m]]; q=l[m];
Usage: rotate(v.begin(), v.begin()+min rotation(v), v.end()); if (sz(str) < length) return {};
while (q<r[m]) { v=t[v][toi(a[q])]; q+=r[v]-l[v]; }
Time: O (N ) 358164, 8 lines H h = 0, pw = 1;
if (q==r[m]) s[m]=v; else s[m]=m+2;
int min_rotation(string s) { q=r[v]-(q-r[m]); m+=2; goto suff; rep(i,0,length)
int a=0, N=sz(s); s += s; } h = h * C + str[i], pw = pw * C;
rep(b,0,N) rep(i,0,N) { } vector<H> ret = {h};
if (a+i == b || s[a+i] < s[b+i]) {b += max(0, i-1); break;} rep(i,length,sz(str)) {
if (s[a+i] > s[b+i]) { a = b; break; } SuffixTree(string a) : a(a) { ret.push_back(h = h * C + str[i] - pw * str[i-length]);
} fill(r,r+N,sz(a)); }
return a; memset(s, 0, sizeof s); return ret;
} memset(t, -1, sizeof t); }
fill(t[1],t[1]+ALPHA,0);
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; }
SuffixArray.h rep(i,0,sz(a)) ukkadd(i, toi(a[i]));
Description: Builds suffix array for a string. sa[i] is the starting index }
of the suffix which is i’th in the sorted suffix array. The returned vector AhoCorasick.h
is of size n + 1, and sa[0] = n. The lcp array contains longest common Description: Aho-Corasick tree is used for multiple pattern matching. Ini-
// example : find longest common substring ( uses ALPHA = 28) tialize the tree with create(patterns). find(word) returns for each position
prefixes for neighbouring strings in the suffix array: lcp[i] = lcp(sa[i], pii best;
sa[i-1]), lcp[0] = 0. The input string must not contain any zero bytes. the index of the longest√ word that ends there, or -1 if none. findAll( , word)
int lcs(int node, int i1, int i2, int olen) {
Time: O (n log n) 38db9f, 23 lines 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
if (l[node] <= i2 && i2 < r[node]) return 2; position (shortest first). Duplicate patterns are allowed; empty patterns are
struct SuffixArray { not. To find the longest words that start at each position, reverse all input.
vi sa, lcp; int mask = 0, len = node ? olen + (r[node] - l[node]) : 0;
rep(c,0,ALPHA) if (t[node][c] != -1) Time: create is O (26N ) where N is the sum of length of patterns. find is
SuffixArray(string& s, int lim=256) { // or basic string<int> O (M ) where M is the length of the word. findAll is O (N M ). 716ac4, 67 lines
int n = sz(s) + 1, k = 0, a, b; mask |= lcs(t[node][c], i1, i2, len);
vi x(all(s)+1), y(n), ws(max(n, lim)), rank(n); if (mask == 3) struct AhoCorasick {
sa = lcp = y, iota(all(sa), 0); best = max(best, {len, r[node] - len}); enum {alpha = 26, first = ’A’};
for (int j = 0, p = 0; p < n; j = max(1, j * 2), lim = p) { return mask; struct Node {
p = j, iota(all(y), n - j); } // (nmatches i s optional )
rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j; static pii LCS(string s, string t) { int back, next[alpha], start = -1, end = -1, nmatches = 0;
fill(all(ws), 0); SuffixTree st(s + (char)(’z’ + 1) + t + (char)(’z’ + 2)); Node(int v) { memset(next, v, sizeof(next)); }
rep(i,0,n) ws[x[i]]++; st.lcs(0, sz(s), sz(s) + 1 + sz(t), 0); };
rep(i,1,lim) ws[i] += ws[i - 1]; return st.best; vector<Node> N;
for (int i = n; i--;) sa[--ws[x[y[i]]]] = y[i]; } vector<int> backp;
swap(x, y), p = 1, x[sa[0]] = 0; }; void insert(string& s, int j) {
rep(i,1,n) a = sa[i - 1], b = sa[i], x[b] = assert(!s.empty());
(y[a] == y[b] && y[a + j] == y[b + j]) ? p - 1 : p++; Hashing.h int n = 0;
} Description: Self-explanatory methods for string hashing. trav(c, s) {
rep(i,1,n) rank[sa[i]] = i; acb5db, 44 lines int& m = N[n].next[c - first];
for (int i = 0, j; i < n - 1; lcp[rank[i++]] = 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); }
for (k && k--, j = sa[rank[i] - 1]; // code , but works on e v i l t e s t data (e . g . Thue−Morse, where else n = m;
s[i + k] == s[j + k]; k++); // 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;
KTH IntervalContainer IntervalCover ConstantIntervals TernarySearch LIS KnuthDP 22
backp.push_back(N[n].end); if (it != is.begin() && (--it)->second >= L) { g(i, to, q);
N[n].end = j; L = min(L, it->first); }
N[n].nmatches++; R = max(R, it->second);
} is.erase(it);
AhoCorasick(vector<string>& pat) { } 10.2 Misc. algorithms
N.emplace_back(-1); return is.insert(before, {L,R});
rep(i,0,sz(pat)) insert(pat[i], i); }
N[0].back = sz(N);
TernarySearch.h
Description: Find the smallest i in [a, b] that maximizes f (i), assuming
N.emplace_back(0); void removeInterval(set<pii>& is, int L, int R) {
that f (a) < . . . < f (i) ≥ · · · ≥ f (b). To reverse which of the sides allows
if (L == R) return;
non-strict inequalities, change the < marked with (A) to <=, and reverse
queue<int> q; auto it = addInterval(is, L, R);
the loop at (B). To minimize f , change it to >, also at (B).
for (q.push(0); !q.empty(); q.pop()) { auto r2 = it->second;
Usage: int ind = ternSearch(0,n-1,[&](int i){return a[i];});
int n = q.front(), prev = N[n].back; if (it->first == L) is.erase(it);
Time: O (log(b − a)) 9155b4, 13 lines
rep(i,0,alpha) { else (int&)it->second = L;
int &ed = N[n].next[i], y = N[prev].next[i]; if (R != r2) is.emplace(R, r2); template<class F>
if (ed == -1) ed = y; } int ternSearch(int a, int b, F f) {
else { assert(a <= b);
N[ed].back = y; while (b - a >= 5) {
(N[ed].end == -1 ? N[ed].end : backp[N[ed].start]) IntervalCover.h int mid = (a + b) / 2;
= N[y].end; Description: Compute indices of smallest set of intervals covering another
if (f(mid) < f(mid+1)) // (A)
N[ed].nmatches += N[y].nmatches; interval. Intervals should be [inclusive, exclusive). To support [inclusive,
a = mid;
q.push(ed); inclusive], change (A) to add || R.empty(). Returns empty set on failure
else
} (or if G is empty).
b = mid+1;
} Time: O (N log N ) 9e9d8d, 19 lines }
} template<class T> rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B)
} vi cover(pair<T, T> G, vector<pair<T, T>> I) { return a;
vi find(string word) { vi S(sz(I)), R; }
int n = 0; iota(all(S), 0);
vi res; // l l count = 0; sort(all(S), [&](int a, int b) { return I[a] < I[b]; });
trav(c, word) { T cur = G.first;
LIS.h
n = N[n].next[c - first]; Description: Compute indices for the longest increasing subsequence.
int at = 0; Time: O (N log N )
res.push_back(N[n].end); while (cur < G.second) { // (A) 5b77eb, 17 lines
// count += N[n ] . nmatches ; pair<T, int> mx = make_pair(cur, -1); template<class I> vi lis(vector<I> S) {
} while (at < sz(I) && I[S[at]].first <= cur) { vi prev(sz(S));
return res; mx = max(mx, make_pair(I[S[at]].second, S[at])); typedef pair<I, int> p;
} at++; vector<p> res;
vector<vi> findAll(vector<string>& pat, string word) { } rep(i,0,sz(S)) {
vi r = find(word); if (mx.second == -1) return {}; p el { S[i], i };
vector<vi> res(sz(word)); cur = mx.first; //S[ i]+1 for non−decreasing
rep(i,0,sz(word)) { R.push_back(mx.second); auto it = lower_bound(all(res), p { S[i], 0 });
int ind = r[i]; } if (it == res.end()) res.push_back(el), it = --res.end();
while (ind != -1) { return R; *it = el;
res[i - sz(pat[ind]) + 1].push_back(ind); } prev[i] = it==res.begin() ?0:(it-1)->second;
ind = backp[ind]; }
} int L = sz(res), cur = res.back().second;
} ConstantIntervals.h vi ans(L);
return res; Description: Split a monotone function on [from, to) into a minimal set of while (L--) ans[L] = cur, cur = prev[cur];
} half-open intervals on which it has the same value. Runs a callback g for return ans;
}; each such interval. }
Usage: constantIntervals(0, sz(v), [&](int x){return v[x];},
[&](int lo, int hi, T val){...});
Time: O k log n
Various (10) k 753a4c, 19 lines 10.3 Dynamic programming
template<class F, class G, class T>
10.1 Intervals void rec(int from, int to, F& f, G& g, int& i, T& p, T q) { KnuthDP.h
if (p == q) return; Description: When doing DP on intervals: a[i][j] = mini<k<j (a[i][k] +
if (from == to) { a[k][j]) + f (i, j), where the (minimal) optimal k increases with both i
IntervalContainer.h g(i, to, p); and j, one can solve intervals in increasing order of length, and search
Description: Add and remove intervals from a set of disjoint intervals. i = to; p = q; k = p[i][j] for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This is
Will merge the added interval with any overlapping intervals in the set when } else { known as Knuth DP. Sufficient criteria for this are if f (b, c) ≤ f (a, d) and
adding. Intervals are [inclusive, exclusive). int mid = (from + to) >> 1; f (a, c) + f (b, d) ≤ f (a, d) + f (b, c) for all a ≤ b ≤ c ≤ d. Consider also:
Time: O (log N ) rec(from, mid, f, g, i, p, f(mid)); LineContainer(ch. Data structures), monotone queues, ternary search.
edce47, 23 lines rec(mid+1, to, f, g, i, p, q); Time: O N 2
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);
KTH DivideAndConquerDP FastMod BumpAllocator SmallPtr BumpAllocatorSTL Unrolling SIMD 23
DivideAndConquerDP.h • #pragma GCC target ("avx,avx2")can double performance Unrolling.h 520e76, 5 lines
Description: Given a[i] = minlo(i)≤k<hi(i) (f (i, k)) where the (minimal)
optimal k increases with i, computes a[i] for i = L..R − 1.
of vectorized code, but causes crashes on old machines. #define F {...; ++i;}
Time: O ((N + (hi − lo)) log N ) int i = from;
d38d2b, 18 lines
• #pragma GCC optimize ("trapv") kills the program on while (i&3 && i < to) F // for alignment , i f needed
struct DP { // Modify at w i l l : while (i + 4 <= to) { F F F F }
int lo(int ind) { return 0; } integer overflows (but is really slow). while (i < to) F
int hi(int ind) { return ind; }
ll f(int ind, int k) { return dp[ind][k]; } FastMod.h SIMD.h
void store(int ind, int k, ll v) { res[ind] = pii(k, v); } Description: Compute a%b about 4 times faster than usual, where b is
Description: Cheat sheet of SSE/AVX intrinsics, for doing arithmetic
constant but not known at compile time. Fails for b = 1. c977c5, 10 lines on several numbers at once. Can provide a constant factor improvement
void rec(int L, int R, int LO, int HI) {
typedef unsigned long long ull; of about 4, orthogonal to loop unrolling. Operations follow the pat-
if (L >= R) return;
typedef __uint128_t L; tern " mm(256)? name (si(128|256)|epi(8|16|32|64)|pd|ps)". Not all
int mid = (L + R) >> 1;
struct FastMod { are described here; grep for mm in /usr/lib/gcc/*/4.9/include/ for
pair<ll, int> best(LLONG_MAX, LO);
ull b, m; more. If AVX is unsupported, try 128-bit operations, ”emmintrin.h” and
rep(k, max(LO,lo(mid)), min(HI,hi(mid)))
FastMod(ull b) : b(b), m(ull((L(1) << 64) / b)) {} #define SSE and MMX before including it. For aligned memory use
best = min(best, make_pair(f(mid, k), k));
ull reduce(ull a) { mm malloc(size, 32) or int buf[N] alignas(32), but prefer loadu/s-
store(mid, best.second, best.first);
ull q = (ull)((L(m) * a) >> 64), r = a - q * b; toreu. 551b82, 43 lines
rec(L, mid, LO, best.second+1);
rec(mid+1, R, best.second, HI); return r >= b ? r - b : r;
#pragma GCC target ("avx2") // or sse4 .1
} }
#include "immintrin.h"
void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); } };
}; typedef __m256i mi;
BumpAllocator.h #define L(x) _mm256_loadu_si256((mi*)&(x))
Description: When you need to dynamically allocate many objects and
10.4 Debugging tricks don’t care about freeing them. ”new X” otherwise has an overhead of some- //
//
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
thing like 0.05us + 16 bytes per allocation. 745db2, 8 lines
// blendv ( epi8 | ps | pd) ( z?y : x) , movemask epi8 ( h i b i t s of bytes )
• signal(SIGSEGV, [](int) { _Exit(0); }); // Either g l o b a l l y or in a single class : // i32gather epi32 (addr , x , 4) : map addr [ ] over 32−b parts of x
static char buf[450 << 20]; // sad epu8 : sum of absolute differences of u8, outputs 4xi64
converts segfaults into Wrong Answers. Similarly one void* operator new(size_t s) { // maddubs epi16 : dot product of unsigned i7 ’ s , outputs 16xi15
can catch SIGABRT (assertion failures) and SIGFPE static size_t i = sizeof buf; // madd epi16 : dot product of signed i16 ’ s , outputs 8xi32
assert(s < i); // extractf128 si256 ( , i ) (256−>128) , cvtsi128 si32 (128−>lo32 )
(zero divisions). _GLIBCXX_DEBUG failures generate return (void*)&buf[i -= s]; // permute2f128 si256(x , x ,1) swaps 128−b i t lanes
SIGABRT (or SIGSEGV on gcc 5.4.0 apparently). } // shuffle epi32 (x , 3∗64+2∗16+1∗4+0) == x for each lane
void operator delete(void*) {} // s h u f f l e e p i 8 (x , y) takes a vector instead of an imm
• feenableexcept(29); kills the program on NaNs
SmallPtr.h // Methods that work with most data types (append e . g . epi32 ) :
(1), 0-divs (4), infinities (8) and denormals (16). Description: A 32-bit pointer that points into BumpAllocator memory. // set1 , blend ( i8?x : y) , add , adds ( sat . ) , mullo , sub , and/or ,
"BumpAllocator.h" 2dd6c9, 10 lines // andnot , abs , min, max, sign (1 ,x) , cmp( gt | eq) , unpack( lo | hi )

10.5 Optimization tricks template<class T> struct ptr {


unsigned ind;
int sumi32(mi m) { union {int v[8]; mi m;} u; u.m = m;
int ret = 0; rep(i,0,8) ret += u.v[i]; return ret; }
ptr(T* p = 0) : ind(p ? unsigned((char*)p - buf) : 0) {
mi zero() { return _mm256_setzero_si256(); }
10.5.1 Bit hacks assert(ind < sizeof buf);
mi one() { return _mm256_set1_epi32(-1); }
}
bool all_zero(mi m) { return _mm256_testz_si256(m, m); }
T& operator*() const { return *(T*)(buf + ind); }
• x & -x is the least bit in x. T* operator->() const { return &**this; }
bool all_one(mi m) { return _mm256_testc_si256(m, one()); }
T& operator[](int a) const { return (&**this)[a]; }
• for (int x = m; x; ) { --x &= m; ... } explicit operator bool() const { return ind; }
ll example_filteredDotProduct(int n, short* a, short* b) {
int i = 0; ll r = 0;
loops over all subset masks of m (except m itself). };
mi zero = _mm256_setzero_si256(), acc = zero;
while (i + 16 <= n) {
• c = x&-x, r = x+c; (((rˆx) >> 2)/c) | r 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);
is the next number after x with the same number of Usage: vector<vector<int, small<int>>> ed(N); mi vp = _mm256_madd_epi16(va, vb);
bb66d4, 14 lines
bits set. char buf[450 << 20] alignas(16);
acc = _mm256_add_epi64(_mm256_unpacklo_epi32(vp, zero),
_mm256_add_epi64(acc, _mm256_unpackhi_epi32(vp, zero)));
size_t buf_ind = sizeof buf; }
• rep(b,0,K) rep(i,0,(1 << K)) union {ll v[4]; mi m;} u; u.m = acc; rep(i,0,4) r += u.v[i];
if (i & 1 << b) D[i] += D[iˆ(1 << b)]; template<class T> struct small { for (;i<n;++i) if (a[i] < b[i]) r += a[i]*b[i]; // <− equiv
typedef T value_type; return r;
computes all sums of subsets. small() {} }
template<class U> small(const U&) {}
T* allocate(size_t n) {
10.5.2 Pragmas buf_ind -= n * sizeof(T);
buf_ind &= 0 - alignof(T);
• #pragma GCC optimize ("Ofast") will make GCC return (T*)(buf + buf_ind);
}
auto-vectorize for loops and optimizes floating points void deallocate(T*, size_t) {}
better (assumes associativity and turns off denormals). };
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

Vous aimerez peut-être aussi