0% found this document useful (0 votes)
32 views23 pages

CP Cheat Sheet

Codebook for competitive programming
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views23 pages

CP Cheat Sheet

Codebook for competitive programming
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

1 Contest 1 8.5 3D . . . . . . . . . . . . . . . . . . 18 g++ "${prog_name}.cpp" -o $prog_name -std=c cf.

bat 5 lines
++17 -g -Wall -Wshadow -fsanitize=address,
undefined && @echo off
2 Mathematics 1 9 Strings 19 "./$prog_name" setlocal
set prog=%1
2.1 Equations . . . . . . . . . . . . . . 1 g++ %prog%.cpp -o %prog% -DDeBuG -std=c++17 -g
2.2 Recurrences . . . . . . . . . . . . . 2 10 Various 20 stdc++.h 34 lines -Wall -Wshadow && .\%prog%
2.3 Trigonometry . . . . . . . . . . . . 2 10.1 Intervals . . . . . . . . . . . . . . . 20 #include <bits/stdc++.h> endlocal
2.4 Geometry . . . . . . . . . . . . . . 2 10.2 Misc. algorithms . . . . . . . . . . 21 using namespace std;
hash.sh
2.5 Derivatives/Integrals . . . . . . . . 2 10.3 Dynamic programming . . . . . . . 21 template <typename T> constexpr
3 lines

2.6 Sums . . . . . . . . . . . . . . . . . 2 # Hashes a file, ignoring all whitespace and


10.4 Debugging tricks . . . . . . . . . . 21 void __print (const T &x);
comments. Use for
2.7 Series . . . . . . . . . . . . . . . . 2 10.5 Optimization tricks . . . . . . . . . 21 # verifying that code was correctly typed.
template<typename T, typename V>
2.8 Probability theory . . . . . . . . . 2 void __print(const pair<T, V> &x) {
cpp -dD -P -fpreprocessed | tr -d ’[:space:]’|
md5sum |cut -c-6
2.9 Markov chains . . . . . . . . . . . 3 cerr << "{"; __print(x.first);
Contest (1) cerr << ", "; __print(x.second); cerr << "}"
stress.sh
; 21 lines
3 Data structures 3 }
instructions.txt 30 lines template <typename T> constexpr
#!/ bin/bash
Compilation: void __print (const T &x) {
4 Numerical 5
1. mkdir WF if constexpr (is_arithmetic_v<T> ||
# prog A and prog B are the executables to
compare
4.1 Polynomials and recurrences . . . . 5 2. vi .bashrc is_same_v<T,const char*> || is_same_v<T,
4.2 Optimization . . . . . . . . . . . . 5 3. Add the line: export PATH="$PATH:$HOME/WF" bool>
prog_A=$1
4. cd WF && vi cf.sh -> Write the compilation || is_same_v<T, string>) cerr << x;
4.3 Matrices . . . . . . . . . . . . . . . 6 commands else {
prog_B=$2
generator=$3
4.4 Fourier transforms . . . . . . . . . 7 5. mv cf.sh cf && chmod +x cf int f = 0; cerr << ’{’;
6. Restart terminal for (auto &i: x)
inp_file="inp_${generator}.txt"
cerr << (f++ ? ", " : ""), __print(i);
5 Number theory 8 Kate: cerr << "}";
out_file1="outA_${generator}.txt"
out_file2="outB_${generator}.txt"
5.1 Modular arithmetic . . . . . . . . . 8 1. Theme: Settings->Configure Kate->Color }
Themes }
5.2 Primality . . . . . . . . . . . . . . 8 void _print() { cerr << "]\n"; }
for ((i = 1; ; ++i)) do
2. Vim mode: Settings->Configure Kate->Editing echo $i
5.3 Divisibility . . . . . . . . . . . . . 9 ->Default input mode. template <typename T, typename... V>
"./$generator" > $inp_file
5.4 Fractions . . . . . . . . . . . . . . 9 Then Vi Input mode->Insert mode->jk = <esc> void _print(T t, V... v) {
"./$prog_A" < $inp_file > $out_file1
3. Word wrap: Settings->Configure Kate-> __print(t);
5.5 Pythagorean Triples . . . . . . . . 9 Appearance->Turn off dynamic w.w. if (sizeof...(v)) cerr << ", ";
"./$prog_B" < $inp_file > $out_file2
diff -w "${out_file1}" "${out_file2}" ||
5.6 Primes . . . . . . . . . . . . . . . . 9 4. Terminal: Make sure View->Tool Views->Show _print(v...);
break
5.7 Estimates . . . . . . . . . . . . . . 9 sidebars is on. Go to }
done
Settings->Configure Kate->Terminal and turn
5.8 Mobius Function . . . . . . . . . . 9 off Hide Konsole. #ifdef DeBuG
notify-send "bug found!!!!"
5. Hotkey for terminal: Change Focus Terminal #define dbg(x...) cerr << "\t\e[93m"<<__func__
Panel to F4. Click "Reassign" <<":"<<__LINE__<<" [" << #x << "] = [";
6 Combinatorial 9
6.1 Permutations . . . . . . . . . . . . 9
when it says it collides with Show Terminal
Panel.
_print(x); cerr << "\e[0m";
#endif Mathematics (2)
6.2 Partitions and subsets . . . . . . . 10
6.3 General purpose numbers . . . . . 10 Fast Compile, Template, Debug: template.cpp 19 lines
2.1 Equations √
1. cd WF && mkdir bits
#include "bits/stdc++.h" 2 −b ± b2 − 4ac
2. Insert stdc++.h ax + bx + c = 0 ⇒ x =
7 Graph 10 3. Compile using the flags of cf.sh using namespace std; 2a
4. cd .. and write template.cpp
7.1 Fundamentals . . . . . . . . . . . . 10 #ifndef DeBuG The extremum is given by x = −b/2a.
7.2 Network flow . . . . . . . . . . . . 11 Windows: #define dbg(...)
1. Using cmd: echo %PATH%. Using Powershell: #endif
7.3 Matching . . . . . . . . . . . . . . 12
echo $env:PATH ed − bf
7.4 DFS algorithms . . . . . . . . . . . 12 2. Add path using cmd: set PATH=%PATH%;C:\ #define rep(i, a, b) for(int i = a; i < (b); x=
ax + by = e ad − bc
7.5 Coloring . . . . . . . . . . . . . . . 13 Program Files\CodeBlocks\MinGW\bin ++i) ⇒
7.6 Heuristics . . . . . . . . . . . . . . 13 It should be the directory where g++ is. #define all(x) begin(x), end(x) cx + dy = f af − ec
3. If we’re using g++ of CodeBlocks, fsanitize #define sz(x) (int)(x).size() y=
7.7 Trees . . . . . . . . . . . . . . . . . 14 using ll = long long; using vi = vector<int>;
ad − bc
won’t be available :(
7.8 Math . . . . . . . . . . . . . . . . . 15 4. Write cf.bat at some directory. Ensure that using pii = pair<int,int>; using pll = pair<ll
directory is in PATH. ,ll>; In general, given an equation Ax = b, the
solution to a variable xi is given by
8 Geometry 15 template<class T> using V = vector<T>;
8.1 Geometric primitives . . . . . . . . 15 cf.sh 6 lines
det A′i
int main() { xi =
8.2 Circles . . . . . . . . . . . . . . . . 16 #!/ bin/bash
ios_base::sync_with_stdio(false);
det A
8.3 Polygons . . . . . . . . . . . . . . . 17 prog_name=$1
cin.tie(0); cout.tie(0); where A′i is A with the i’th column replaced by
}
8.4 Misc. Point Set Problems . . . . . 17 b.
BRACU instructions cf stdc++ template cf hash stress 2
2.2 Recurrences α+β 2.6 Sums 2.8.1 Discrete distributions
a+b tan
If an = c1 an−1 + · · · + ck an−k , and r1 , . . . , rk are Law of tangents: = 2 a a+1 bcb+1 − ca Binomial distribution
a−b α−β c +c + ··· + c = , c ̸= 1
distinct roots of xk − c1 xk−1 − · · · − ck , there tan c−1
2 The number of successes in n independent
are d1 , . . . , dk s.t.
2.4.2 Quadrilaterals yes/no experiments, each which yields success
n
an = d1 r1n + · · · + dk rkn . With side lengths a, b, c, d, diagonals e, f ,
X n(n + 1) with probability p is
k= Bin(n, p), n = 1, 2, . . . , 0 ≤ p ≤ 1.
diagonals angle θ, area A and magic flux 2
k=1
Non-distinct roots r become polynomial factors, F = b2 + d2 − a2 − c2 : n
e.g. an = (d1 n + d2 )rn . n(2n + 1)(n + 1)
X !
k2 = n k
6 p(k) = p (1 − p)n−k
2.3 Trigonometry p k=1 k
4A = 2ef · sin θ = F tan θ = 4e2 f 2 − F 2 Xn
n2 (n + 1)2
sin(v + w) = sin v cos w + cos v sin w k3 =
4
cos(v + w) = cos v cos w − sin v sin w For cyclic quadrilaterals the sum of opposite k=1 µ = np, σ 2 = np(1 − p)
◦ n
angles
pis 180 , ef = ac + bd, and
X n(n + 1)(2n + 1)(3n2 + 3n − 1)
k4 = Bin(n, p) is approximately Po(np) for small
A = (p − a)(p − b)(p − c)(p − d). 30
k=1 p.
tan v + tan w 2.4.3 Spherical coordinates First success distribution
tan(v + w) =
1 − tan v tan w z The number of trials needed to get the first
v+w v−w
sin v + sin w = 2 sin cos r 2.7 Series success in independent yes/no experiments, each
2 2
v+w v−w y ex = 1 + x +
x2
+
x3
+ . . . , (−∞ < x < ∞)
which yields success with probability p is
cos v + cos w = 2 cos cos 2! 3! Fs(p), 0 ≤ p ≤ 1.
2 2
(V + W ) tan(v − w)/2 = (V − W ) tan(v + w)/2 x ln(1 + x) = x −
x2 x3 x4
+ − + . . . , (−1 < x ≤ 1) p(k) = p(1 − p)k−1 , k = 1, 2, . . .
2 3 4
where V, W are lengths of sides opposite angles p
2 + y2 + z2
x = r sin θ cos ϕ r = xp √ x x2 2x3 5x4 1 2 1−p
v, w.
y = r sin θ sin ϕ θ = acos(z/ x2 + y 2 + z 2 ) 1 + x = 1+ − + − + . . . , (|x| ≤ 1) µ= ,σ =
2 8 32 128 p p2
a cos x + b sin x = r cos(x − ϕ) z = r cos θ ϕ = atan2(y, x)
x3 x5 x7 Poisson distribution
a sin x + b cos x = r sin(x + ϕ) 2.5 Derivatives/Integrals sin x = x − + − + . . . , (−∞ < x < ∞)
3! 5! 7!
√ The number of events occurring in a fixed period
where r = a2 + b2 , ϕ = atan2(b, a). d 1 x2 x4 x6 of time t if these events occur with a known
arcsin x = √ cos x = 1 − + − + . . . , (−∞ < x < ∞)
2.4 Geometry dx 1 − x2 2! 4! 6! average rate κ and independently of the time
d 1 since the last event is Po(λ), λ = tκ.
2.4.1 Triangles arccos x = − √
dx 1 − x2 2.8 Probability theory
Side lengths: a, b, c
a+b+c d Let X be a discrete random variable with λk
Semiperimeter: p = tan x = 1 + tan2 x probability pX (x) of assuming the value x. It p(k) = e−λ , k = 0, 1, 2, . . .
2 dx k!
will then havePan expected value (mean)
p
Area: A = p(p − a)(p − b)(p − c) d 1
abc arctan x = µ = E(X) = x xpX (x) and variance
Circumradius: R = dx 1 + x2 2 2 µ = λ, σ 2 = λ
4A
Z
ln | cos ax| σ
P = V (X) = E(X ) − (E(X))2 =
A tan ax = − 2
Inradius: r = a x (x − E(X)) pX (x) where σ is the standard 2.8.2 Continuous distributions
p deviation. If X is instead continuous it will have
Uniform distribution
Z
Length of median (divides triangle into two sin ax − ax cos ax
x sin ax = a probability density function fX (x) and the
equal-area a2
√ triangles): √ sums above will instead be integrals with pX (x) If the probability density function is constant
ma = 21 2b2 + 2c2 − a2
Z
2 π replaced by fX (x). between a and b and 0 elsewhere it is
e−x = erf(x)
Length
v of "bisector (divides angles in two): 2 U(a, b), a < b.
Z ax Expectation is linear:
u  2 # e
u
sa = tbc 1 −
a xeax dx = 2 (ax − 1)  1
a a<x<b
b+c E(aX + bY ) = aE(X) + bE(Y ) f (x) = b−a
0 otherwise
Law of sines: Integration by parts:
sin α sin β sin γ 1 For independent X and Y ,
= = = Z b Z b
a b c 2R
f (x)g(x)dx = [F (x)g(x)]ba − ′
F (x)g (x)dx a+b 2 (b − a)2
Law of cosines: a2 = b2 + c2 − 2bc cos α a a
V (aX + bY ) = a2 V (X) + b2 V (Y ). µ=
2
,σ =
12
BRACU OrderStatisticTree HashMap SegmentTree segtree UnionFindRollback 3
Exponential distribution A Markov chain is an A-chain if the states can Tree(int n = 0, T def = unit) : s(2*n, def), if (r <= mid) res = get(u+1, b, mid, l, r)
be partitioned into two sets A and G, such that n(n) {} ;
The time between events in a Poisson process is void update(int pos, T val) { else if (mid < l) res = get(rc, mid+1, e,
Exp(λ), λ > 0. all states in A are absorbing (pii = 1), and all for (s[pos += n] = val; pos /= 2;) l, r);
states in G leads to an absorbing state in A. s[pos] = f(s[pos * 2], s[pos * 2 + 1]); else res = get(u+1, b, mid, l, r) + get(rc
} , mid+1, e, l, r);
λe−λx x ≥ 0 The probability for absorption in state i ∈ A,

f (x) = T query(int b, int e) { // query [ b , e) t[u] = t[u+1] + t[rc]; return res;
0 x<0 when the initial
P state is j, is T ra = unit, rb = unit; }
aij = pij + k∈G aik pkj . The expected time for (b += n, e += n; b < e; b /= 2, e /= };
1 2 1 2) {
µ= ,σ = 2 until absorption, when the initial state is i, is if (b % 2) ra = f(ra, s[b++]); /* Segment Tree
λ λ
P
ti = 1 + k∈G pki tk . if (e % 2) rb = f(s[--e], rb); ===============
} Inspiration : tourist , atcoder library
Normal distribution return f(ra, rb);
Most real random values with mean µ and Data structures (3) };
} (1) Declaration :
Create a node class (sample below) .
variance σ 2 are well described by OrderStatisticTree.h node class must have the following :
N (µ, σ 2 ), σ > 0. Description: A set (not multiset!) with support for
* A constructor ( to create empty nodes and
finding the n’th element, and finding the index of an el-
(x−µ)2 ement. To get a map, change null type.
segtree.cpp deb606, 92 lines
also to make inplace nodes) .
1 − * + operator : returns a node which contains
f (x) = √ e 2σ 2 Time: O (log N ) 782797, 16 lines template<class S> struct segtree { the merged information of two nodes .
2πσ 2 int n; vector<S> t; * upd(b , e , . . . ) : updates t h i s node
#include <bits/extc++.h>
void init(int _) { n = _; t.assign(n+n-1, S representing the range [ b , e ] using
using namespace __gnu_pbds;
If X1 ∼ N (µ1 , σ12 ) and X2 ∼ N (µ2 , σ22 ) ()); } information from . . .
then void init(const vector<S>& v) {
template<class T>
n = sz(v); t.assign(n + n - 1, S()); Now, segtree<node> T; declares the tree .
using Tree = tree<T, null_type, less<T>,
build(0,0,n-1,v);
aX1 + bX2 + c ∼ N (µ1 + µ2 + c, a2 σ12 + b2 σ22 ) rb_tree_tag,
} template <typename... T>
You can use T. i n i t (100) to create an empty
tree_order_statistics_node_update>; tree of 100 nodes in [0 , 100) range .
void upd(int l, int r, const T&... v) { You can also make a vector<node> v ; Then put
assert(0 <= l && l <= r && r < n);
2.9 Markov chains void example() {
Tree<int> t, t2; t.insert(8);
upd(0, 0, n-1, l, r, v...);
values in the vector v and make the
tree using
A Markov chain is a discrete random process } v by , T. i n i t (v) ; This works in linear time
auto it = t.insert(10).first;
S get(int l, int r) { and i s faster than updating each
with the property that the next state depends assert(it == t.lower_bound(9));
assert(0 <= l && l <= r && r < n);
assert(t.order_of_key(10) == 1); individually .
only on the current state. Let X1 , X2 , . . . be a assert(t.order_of_key(11) == 2);
return get(0, 0, n-1, l, r);
}
sequence of random variables generated by the assert(*t.find_by_order(0) == 8);
private:
(2) Usage :
Markov process. Then there is a transition t.join(t2); // assuming T < T2 or T > T2, (2.1) i n i t ( int s i z ) or i n i t ( vector ) :
inline void push(int u, int b, int e) { Described above
merge t2 into t
matrix P = (pij ), with }
if (t[u].lazy == 0) return;
int mid = (b+e)>>1, rc = u+((mid-b+1)<<1);
pij = Pr(Xn = i|Xn−1 = j), and p(n) = Pn p(0) t[u+1].upd(b, mid, t[u].lazy);
(2.2) upd( l , r , . . . v) :
Update the range [ l , r ] with the
is the probability distribution for Xn (i.e., HashMap.h t[rc].upd(mid+1, e, t[u].lazy); information in . . .
(n) t[u].lazy = 0;
pi = Pr(Xn = i)), where p(0) is the initial Description: Hash map with mostly the same API as
}
Make sure the number of elements and the
unordered map, but ∼3x faster. Uses 1.5x memory. Ini- order of them you put here i s the
distribution. tial capacity must be a power of 2 (if provided). void build(int u, int b, int e, const vector exact same
d77092, 7 lines
<S>& v) { as you declared in your node . upd()
π is a stationary distribution if π = πP. If the #include <bits/extc++.h> if (b == e) return void(t[u] = v[b]); function .
// To use most b i t s rather than j u s t the
Markov chain is irreducible (it is possible to get lowest ones :
int mid = (b+e)>>1, rc = u+((mid-b+1)<<1); */
build(u+1, b, mid, v); build(rc, mid+1, e,
to any state from any state), then πi = E(T1 i ) struct chash { // large odd number for C v);
const uint64_t C = ll(4e18 * acos(0)) | 71; struct node {
where E(Ti ) is the expected time between two t[u] = t[u+1] + t[rc]; ll sum;
ll operator()(ll x) const { return } template<typename... T>
visits in state i. πj /πi is the expected number of __builtin_bswap64(x*C); } void upd(int u, int b, int e, int l, int r,
ll lazy;
visits in state j between two visits in state }; const T&... v) { node(ll _a = 0, ll _b = 0) : sum(_a), lazy(
__gnu_pbds::gp_hash_table<ll,int,chash> h({},{ if (l <= b && e <= r) return t[u].upd(b, e
i. },{},{},{1<<16}); _b) {}
, v...);
For a connected, undirected and non-bipartite push(u, b, e); node operator+(const node &obj) {
SegmentTree.h int mid = (b+e)>>1, rc = u+((mid-b+1)<<1); return {sum + obj.sum, 0};
graph, where the transition probability is if (l <= mid) upd(u+1, b, mid, l, r, v...)
Description: Zero-indexed max-tree. Bounds are inclu- }
uniform among all neighbors, πi is proportional sive to the left and exclusive to the right. Can be changed ;
if (mid < r) upd(rc, mid+1, e, l, r, v...)
to node i’s degree. by modifying T, f and unit.
;
void upd(int b, int e, ll x) {
Time: O (log N ) 0f4bdb, 19 lines
sum += (e - b + 1) * x;
t[u] = t[u+1] + t[rc];
A Markov chain is ergodic if the asymptotic struct Tree { }
lazy += x;
}
distribution is independent of the initial typedef int T; S get(int u, int b, int e, int l, int r) { };
distribution. A finite Markov chain is ergodic iff static constexpr T unit = INT_MIN; if (l <= b && e <= r) return t[u];
T f(T a, T b) { return max(a, b); } // (any push(u, b, e);
it is irreducible and aperiodic (i.e., the gcd of associative fn ) S res; int mid = (b+e)>>1, rc = u+((mid-b
cycle lengths is 1). limk→∞ Pk = 1π. vector<T> s; int n; +1)<<1);
BRACU SubMatrix Matrix LineContainer Treap FenwickTree FenwickTree2d RMQ 4
UnionFindRollback.h vector<T> operator*(const vector<T>& vec) Time: O (log N ) 9556fc, 55 lines
Description: Disjoint-set data structure with undo. If const { struct FT {
undo is not needed, skip st, time() and rollback(). vector<T> ret(N); struct Node { vector<ll> s;
Usage: int t = uf.time(); ...; uf.rollback(t); rep(i,0,N) rep(j,0,N) ret[i] += d[i][j] * Node *l = 0, *r = 0; FT(int n) : s(n) {}
Time: O (log(N )) vec[j]; int val, y, c = 1; void update(int pos, ll dif) { // a [ pos ] +=
de4ad0, 21 lines Node(int val) : val(val), y(rand()) {}
return ret; dif
struct RollbackUF { } void recalc(); for (; pos < sz(s); pos |= pos + 1) s[pos]
vi e; vector<pii> st; M operator^(ll p) const { }; += dif;
RollbackUF(int n) : e(n, -1) {} assert(p >= 0); }
int size(int x) { return -e[find(x)]; } M a, b(*this); int cnt(Node* n) { return n ? n->c : 0; } ll query(int pos) { // sum of values in [0 ,
int find(int x) { return e[x] < 0 ? x : find rep(i,0,N) a.d[i][i] = 1; void Node::recalc() { c = cnt(l) + cnt(r) + 1; pos)
(e[x]); } while (p) { } ll res = 0;
int time() { return sz(st); } if (p&1) a = a*b; for (; pos > 0; pos &= pos - 1) res += s[
void rollback(int t) { b = b*b; template<class F> void each(Node* n, F f) { pos-1];
for (int i = time(); i --> t;) p >>= 1; if (n) { each(n->l, f); f(n->val); each(n->r return res;
e[st[i].first] = st[i].second; } , f); } }
st.resize(t); return a; } int lower_bound(ll sum) {// min pos s t sum
} } of [0 , pos ] >= sum
bool join(int a, int b) { }; pair<Node*, Node*> split(Node* n, int k) { // Returns n i f no sum i s >= sum, or =1 i f
a = find(a), b = find(b); if (!n) return {}; empty sum i s .
if (a == b) return false; if (cnt(n->l) >= k) { // ”n=>val >= k” for if (sum <= 0) return -1;
if (e[a] > e[b]) swap(a, b); LineContainer.h lower bound(k) int pos = 0;
st.push_back({a, e[a]}); Description: Container where you can add lines of the auto pa = split(n->l, k); for (int pw = 1 << 25; pw; pw >>= 1) {
st.push_back({b, e[b]}); form kx+m, and query maximum values at points x. Use- n->l = pa.second; if (pos + pw <= sz(s) && s[pos + pw-1] <
e[a] += e[b]; e[b] = a; ful for dynamic programming (“convex hull trick”). n->recalc(); sum)
return true; Time: O (log N ) return {pa.first, n}; pos += pw, sum -= s[pos-1];
} 8ec1c7, 30 lines } else { }
}; struct Line { auto pa = split(n->r, k - cnt(n->l) - 1); return pos;
mutable ll k, m, p; // and j u s t ”k” }
bool operator<(const Line& o) const { return n->r = pa.first; };
SubMatrix.h k < o.k; } n->recalc();
Description: Calculate submatrix sums quickly, given bool operator<(ll x) const { return p < x; } return {n, pa.second};
upper-left and lower-right corners (half-open). }; } FenwickTree2d.h
Usage: SubMatrix<int> m(matrix); } Description: Computes sums a[i,j] for all i<I, j<J, and
m.sum(0, 0, 2, 2); // top left 4 elements struct LineContainer : multiset<Line, less<>> increases single elements a[i,j]. Requires that the ele-
Time: O N 2 + Q

c59ada, 13 lines { Node* merge(Node* l, Node* r) { ments to be updated are known in advance (call fakeUp-
// ( for doubles , use i n f = 1/.0 , div (a , b) = if (!l) return r; date() before init()).
template<class T> Time: O log2 N . (Use persistent segment trees for

a/b) if (!r) return l;
struct SubMatrix { O (log N ).)
static const ll inf = LLONG_MAX; if (l->y > r->y) {
vector<vector<T>> p;
ll div(ll a, ll b) { // floored division l->r = merge(l->r, r); "FenwickTree.h" 157f07, 22 lines
SubMatrix(vector<vector<T>>& v) {
return a / b - ((a ^ b) < 0 && a % b); } l->recalc(); struct FT2 {
int R = sz(v), C = sz(v[0]);
bool isect(iterator x, iterator y) { return l; vector<vi> ys; vector<FT> ft;
p.assign(R+1, vector<T>(C+1));
if (y == end()) return x->p = inf, 0; } else { FT2(int limx) : ys(limx) {}
rep(r,0,R) rep(c,0,C)
if (x->k == y->k) x->p = x->m > y->m ? inf r->l = merge(l, r->l); void fakeUpdate(int x, int y) {
p[r+1][c+1] = v[r][c] + p[r][c+1] + p[r
: -inf; r->recalc(); for (; x < sz(ys); x |= x + 1) ys[x].
+1][c] - p[r][c];
else x->p = div(y->m - x->m, x->k - y->k); return r; push_back(y);
}
return x->p >= y->p; } }
T sum(int u, int l, int d, int r) {
} } void init() {
return p[d][r] - p[d][l] - p[u][r] + p[u][
void add(ll k, ll m) { for (vi& v : ys) sort(all(v)), ft.
l];
auto z = insert({k, m, 0}), y = z++, x = y Node* ins(Node* t, Node* n, int pos) { emplace_back(sz(v));
}
; auto pa = split(t, pos); }
};
while (isect(y, z)) z = erase(z); return merge(merge(pa.first, n), pa.second); int ind(int x, int y) {
if (x != begin() && isect(--x, y)) isect(x } return (int)(lower_bound(all(ys[x]), y) -
Matrix.h , y = erase(y)); ys[x].begin()); }
Description: Basic operations on square matrices. while ((y = x) != begin() && (--x)->p >= y // Example application : move the range [ l , r ) void update(int x, int y, ll dif) {
Usage: Matrix<int, 3> A; ->p) to index k for (; x < sz(ys); x |= x + 1)
A.d = {{{{1,2,3}}, {{4,5,6}}, {{7,8,9}}}}; isect(x, erase(y)); void move(Node*& t, int l, int r, int k) { ft[x].update(ind(x, y), dif);
vector<int> vec = {1,2,3}; } Node *a, *b, *c; }
vec = (AˆN) * vec; ll query(ll x) { tie(a,b) = split(t, l); tie(b,c) = split(b, ll query(int x, int y) {
c43c7d, 26 lines assert(!empty()); r - l); ll sum = 0;
template<class T, int N> struct Matrix { auto l = *lower_bound(x); if (k <= l) t = merge(ins(a, b, k), c); for (; x; x &= x - 1)
typedef Matrix M; return l.k * x + l.m; else t = merge(a, ins(c, b, k - r)); sum += ft[x-1].query(ind(x-1, y));
array<array<T, N>, N> d{}; } } return sum;
M operator*(const M& m) const { }; }
M a; };
rep(i,0,N) rep(j,0,N) FenwickTree.h
rep(k,0,N) a.d[i][j] += d[i][k]*m.d[k][j Treap.h Description: Computes partial sums a[0] + a[1] + ...
]; Description: A short self-balancing tree. It acts as a se- + a[pos - 1], and updates single elements a[i], taking the RMQ.h
return a; quential container with log-time splits/joins, and is easy difference between the old and new value. Description: Range Minimum Queries on an array. Re-
} to augment with additional data. Time: Both operations are O (log N ). e62fac, 22 lines turns min(V[a], V[a + 1], ... V[b - 1]) in constant time.
BRACU MoQueries Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence GoldenSectionSearch 5
Usage: RMQ rmq(values); for (int y : ed[x]) if (y != p) f(y, x, ! dr.push_back(xmin-1); C.resize(L + 1); C.erase(C.begin());
rmq.query(inclusive, exclusive); dep, f); dr.push_back(xmax+1); for (ll& x : C) x = (mod - x) % mod;
Time: O (|V | log |V | + Q) 510c32, 16 lines
if (!dep) I[x] = N++; sort(all(dr)); return C;
R[x] = N; rep(i,0,sz(dr)-1) { }
template<class T> }; double l = dr[i], h = dr[i+1];
struct RMQ { dfs(root, -1, 0, dfs); bool sign = p(l) > 0;
vector<vector<T>> jmp; #define K(x) pii(I[x[0]] / blk, I[x[1]] ^ -(I[ if (sign ^ (p(h) > 0)) {
LinearRecurrence.h
Description: Generates the P k’th term of an n-order
RMQ(const vector<T>& V) : jmp(1, V) { x[0]] / blk & 1)) rep(it,0,60) { // while (h = l > 1e=8)
for (int pw = 1, k = 1; pw * 2 <= sz(V); iota(all(s), 0); double m = (l + h) / 2, f = p(m);
linear recurrence S[i] = j S[i − j − 1]tr[j], given
pw *= 2, ++k) { sort(all(s), [&](int s, int t){ return K(Q[s if ((f <= 0) ^ sign) l = m; S[0 . . . ≥ n − 1] and tr[0 . . . n − 1]. Faster than matrix
jmp.emplace_back(sz(V) - pw * 2 + 1); ]) < K(Q[t]); }); else h = m; multiplication. Useful together with Berlekamp–Massey.
rep(j,0,sz(jmp[k])) for (int qi : s) rep(end,0,2) { } Usage: linearRec({0, 1}, {1, 1}, k) // k’th
jmp[k][j] = min(jmp[k - 1][j], jmp[k - int &a = pos[end], b = Q[qi][end], i = 0; ret.push_back((l + h) / 2); Fibonacci number
1][j + pw]); #define step(c) { if (in[c]) { del(a, end); in } Time: O n2 log k f4e444, 26 lines
} [a] = 0; } \ }
} typedef vector<ll> Poly;
else { add(c, end); in[c] = return ret; ll linearRec(Poly S, Poly tr, ll k) {
T query(int a, int b) { 1; } a = c; } }
assert(a < b); // or return i n f i f a == b int n = sz(tr);
while (!(L[b] <= L[a] && R[a] <= R[b]))
int dep = 31 - __builtin_clz(b - a); I[i++] = b, b = par[b]; auto combine = [&](Poly a, Poly b) {
return min(jmp[dep][a], jmp[dep][b - (1 << while (a != b) step(par[a]); PolyInterpolate.h Poly res(n * 2 + 1);
dep)]); while (i--) step(I[i]); Description: Given n points (x[i], y[i]), computes an n-
} rep(i,0,n+1) rep(j,0,n+1)
if (end) res[qi] = calc(); 1-degree polynomial p that passes through them: p(x) =
}; res[i + j] = (res[i + j] + a[i] * b[j])
} a[0] ∗ x0 + ... + a[n − 1] ∗ xn−1 . For numerical precision, % mod;
return res; pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1. for (int i = 2 * n; i > n; --i) rep(j,0,n)
MoQueries.h } Time: O n2 08bf48, 13 lines res[i - 1 - j] = (res[i - 1 - j] + res[i
Description: Answer interval or tree path queries by ] * tr[j]) % mod;
finding an approximate TSP through the queries, and typedef vector<double> vd;
vd interpolate(vd x, vd y, int n) { res.resize(n + 1);
moving from one query to the next by adding/removing
points at the ends. If values are on tree edges, change
Numerical (4) vd res(n), temp(n); return res;
rep(k,0,n-1) rep(i,k+1,n) };
step to add/remove the edge (a, c) and remove the ini-
tial add call (but
√ keep in). 4.1 Polynomials and y[i] = (y[i] - y[k]) / (x[i] - x[k]);
double last = 0; temp[0] = 1; Poly pol(n + 1), e(pol);
Time: O N Q a12ef4, 49 lines
recurrences rep(k,0,n) rep(i,0,n) { pol[0] = e[1] = 1;
void add(int ind, int end) { ... } // add a [ res[i] += y[k] * temp[i];
ind ] (end = 0 or 1) Polynomial.h c9b7b0, 17 lines swap(last, temp[i]); for (++k; k; k /= 2) {
void del(int ind, int end) { ... } // remove a temp[i] -= last * x[k]; if (k % 2) pol = combine(pol, e);
struct Poly {
[ ind ] } e = combine(e, e);
vector<double> a;
int calc() { ... } // compute current answer return res; }
double operator()(double x) const {
double val = 0; }
vi mo(vector<pii> Q) { ll res = 0;
for (int i = sz(a); i--;) (val *= x) += a[
int L = 0, R = 0, blk = 350; // ∼N/sqrt (Q) rep(i,0,n) res = (res + pol[i + 1] * S[i]) %
i];
vi s(sz(Q)), res = s; return val;
BerlekampMassey.h mod;
#define K(x) pii(x.first/blk, x.second ^ -(x. Description: Recovers any n-order linear recurrence re- return res;
}
first/blk & 1)) lation from the first 2n terms of the recurrence. Useful }
void diff() {
iota(all(s), 0); for guessing linear recurrences after brute-forcing the first
rep(i,1,sz(a)) a[i-1] = i*a[i];
terms. Should work on any field, but numerical stability
sort(all(s), [&](int s, int t){ return K(Q[s
]) < K(Q[t]); });
a.pop_back();
for floats is not guaranteed. Output will have size ≤ n. 4.2 Optimization
}
for (int qi : s) { void divroot(double x0) {
Usage: berlekampMassey({0, 1, 1, 3, 5, 11}) // GoldenSectionSearch.h
pii q = Q[qi]; {1, 2}
double b = a.back(), c; a.back() = 0;
Time: O N 2

while (L > q.first) add(--L, 0); for(int i=sz(a)-1; i--;) c = a[i], a[i] = Description: Finds the argument minimizing the func-
while (R < q.second) add(R++, 1); "../number-theory/ModPow.h" 96548b, 20 lines
a[i+1]*x0+b, b=c; tion f in the interval [a, b] assuming f is unimodal on the
while (L < q.first) del(L++, 0); a.pop_back(); vector<ll> berlekampMassey(vector<ll> s) { interval, i.e. has only one local minimum. The maximum
while (R > q.second) del(--R, 1); } int n = sz(s), L = 0, m = 0; error in the result is eps. Works equally well for maxi-
res[qi] = calc(); }; vector<ll> C(n), B(n), T; mization with a small change in the code. See Ternary-
} C[0] = B[0] = 1; Search.h in the Various chapter for a discrete version.
return res; Usage: double func(double x) { return
} PolyRoots.h ll b = 1; 4+x+.3*x*x; }
Description: Finds the real roots to a polynomial. rep(i,0,n) { ++m;
Usage: polyRoots({{2,-3,1}},-1e9,1e9) // solve double xmin = gss(-1000,1000,func);
vi moTree(vector<array<int, 2>> Q, vector<vi>& ll d = s[i] % mod; Time: O (log((b − a)/ϵ))
ed, int root=0){ xˆ2-3x+2 = 0 rep(j,1,L+1) d = (d + C[j] * s[i - j]) % 31d45b, 14 lines
Time: O n2 log(1/ϵ)

int N = sz(ed), pos[2] = {}, blk = 350; // ∼ mod; double gss(double a, double b, double (*f)(
N/sqrt (Q) "Polynomial.h" b00bfe, 23 lines if (!d) continue; double)) {
vi s(sz(Q)), res = s, I(N), L(N), R(N), in(N vector<double> polyRoots(Poly p, double xmin, T = C; ll coef = d * modpow(b, mod-2) % double r = (sqrt(5)-1)/2, eps = 1e-7;
), par(N); double xmax) { mod; double x1 = b - r*(b-a), x2 = a + r*(b-a);
add(0, 0), in[0] = 1; if (sz(p.a) == 2) { return {-p.a[0]/p.a[1]}; rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) double f1 = f(x1), f2 = f(x2);
auto dfs = [&](int x, int p, int dep, auto& } % mod; while (b-a > eps)
f) -> void { vector<double> ret; if (2 * L > i) continue; if (f1 < f2) { //change to > to find
par[x] = p; Poly der = p; L = i + 1 - L; B = T; b = d; m = 0; maximum
L[x] = N; der.diff(); } b = x2; x2 = x1; f2 = f1;
if (dep) I[x] = N++; auto dr = polyRoots(der, xmin, xmax); x1 = b - r*(b-a); f1 = f(x1);
BRACU HillClimbing Integrate IntegrateAdaptive Simplex Determinant IntDeterminant SolveLinear SolveLinear2 6
} else { } if (r == -1 || MP(D[i][n+1] / D[i][s], a[i][k] = (a[i][k] - a[j][k] * t) %
a = x1; x1 = x2; f1 = f2; B[i]) mod;
x2 = a + r*(b-a); f2 = f(x2); < MP(D[r][n+1] / D[r][s], swap(a[i], a[j]);
} B[r])) r = i; ans *= -1;
return a; Simplex.h } }
} Description: Solves a general linear maximization prob- if (r == -1) return false; }
lem: maximize cT x subject to Ax ≤ b, x ≥ 0. Returns pivot(r, s); ans = ans * a[i][i] % mod;
-inf if there is no solution, inf if there are arbitrarily good } if (!ans) return 0;
HillClimbing.h solutions, or the maximum value of cT x otherwise. The } }
Description: Poor man’s optimization for unimodal input vector is set to an optimal x (or in the unbounded return (ans + mod) % mod;
functions. 8eeeaf, 14 lines case, an arbitrary solution fulfilling the constraints). Nu- T solve(vd &x) { }
typedef array<double, 2> P; merical stability is not guaranteed. For better perfor- int r = 0;
mance, define variables such that x = 0 is viable. rep(i,1,m) if (D[i][n+1] < D[r][n+1]) r =
template<class F> pair<double, P> hillClimb(P Usage: vvd A = {{1,-1}, {-1,1}, {-1,-2}}; i; SolveLinear.h
start, F f) { vd b = {1,1,-4}, c = {-1,-1}, x; if (D[r][n+1] < -eps) { Description: Solves A ∗ x = b. If there are multiple
pair<double, P> cur(f(start), start); T val = LPSolver(A, b, c).solve(x); pivot(r, n); solutions, an arbitrary one is returned. Returns rank, or
for (double jmp = 1e9; jmp > 1e-20; jmp /= Time: O (N M ∗ #pivots), where a pivot may be e.g. an if (!simplex(2) || D[m+1][n+1] < -eps) -1 if no solutions.
 Data in A and b is lost.
2) { edge relaxation. O (2n ) in the general case.aa8530, 68 lines return -inf; Time: O n2 m 44c9ab, 38 lines
rep(j,0,100) rep(dx,-1,2) rep(dy,-1,2) { rep(i,0,m) if (B[i] == -1) {
typedef double T; // long double , Rational , typedef vector<double> vd;
P p = cur.second; int s = 0;
double + mod<P>... const double eps = 1e-12;
p[0] += dx*jmp; rep(j,1,n+1) ltj(D[i]);
typedef vector<T> vd; pivot(i, s);
p[1] += dy*jmp; typedef vector<vd> vvd; int solveLinear(vector<vd>& A, vd& b, vd& x) {
cur = min(cur, make_pair(f(p), p)); }
int n = sz(A), m = sz(x), rank = 0, br, bc;
} }
const T eps = 1e-8, inf = 1/.0; if (n) assert(sz(A[0]) == m);
} bool ok = simplex(1); x = vd(n);
#define MP make_pair vi col(m); iota(all(col), 0);
return cur; rep(i,0,m) if (B[i] < n) x[B[i]] = D[i][n
#define ltj(X) if(s == -1 || MP(X[j],N[j]) < +1];
} MP(X[s],N[s])) s=j rep(i,0,n) {
return ok ? D[m][n+1] : inf;
double v, bv = 0;
}
Integrate.h struct LPSolver { };
rep(r,i,n) rep(c,i,m)
Description: Simple integration of a function over an int m, n; if ((v = fabs(A[r][c])) > bv)
interval using Simpson’s rule. The error should be pro- vi N, B; br = r, bc = c, bv = v;
portional to h4 , although in practice you will want to vvd D; 4.3 Matrices if (bv <= eps) {
rep(j,i,n) if (fabs(b[j]) > eps) return
verify that the result is stable to desired precision when Determinant.h -1;
epsilon changes. LPSolver(const vvd& A, const vd& b, const vd Description: Calculates determinant of a matrix. De-
4756fc, 7 lines
& c) : break;
template<class F> stroys the matrix.
m(sz(b)), n(sz(c)), N(n+1), B(m), D(m+2, }
Time: O N 3

double quad(double a, double b, F f, const int vd(n+2)) { bd5cec, 15 lines swap(A[i], A[br]);
n = 1000) { rep(i,0,m) rep(j,0,n) D[i][j] = A[i][j]; double det(vector<vector<double>>& a) { swap(b[i], b[br]);
double h = (b - a) / 2 / n, v = f(a) + f(b); rep(i,0,m) { B[i] = n+i; D[i][n] = -1; D int n = sz(a); double res = 1; swap(col[i], col[bc]);
rep(i,1,n*2) [i][n+1] = b[i];} rep(i,0,n) { rep(j,0,n) swap(A[j][i], A[j][bc]);
v += f(a + i*h) * (i&1 ? 4 : 2); rep(j,0,n) { N[j] = j; D[m][j] = -c[j]; int b = i; bv = 1/A[i][i];
return v * h / 3; } rep(j,i+1,n) if (fabs(a[j][i]) > fabs(a[b rep(j,i+1,n) {
} N[n] = -1; D[m+1][n] = 1; ][i])) b = j; double fac = A[j][i] * bv;
} if (i != b) swap(a[i], a[b]), res *= -1; b[j] -= fac * b[i];
res *= a[i][i]; rep(k,i+1,m) A[j][k] -= fac*A[i][k];
IntegrateAdaptive.h void pivot(int r, int s) { if (res == 0) return 0; }
Description: Fast integration using an adaptive Simp-
T *a = D[r].data(), inv = 1 / a[s]; rep(j,i+1,n) { rank++;
son’s rule.
rep(i,0,m+2) if (i != r && abs(D[i][s]) > double v = a[j][i] / a[i][i]; }
Usage: double sphereVolume = quad(-1, 1,
[](double x) { eps) { if (v != 0) rep(k,i+1,n) a[j][k] -= v *
T *b = D[i].data(), inv2 = b[s] * inv; a[i][k]; x.assign(m, 0);
return quad(-1, 1, [&](double y) {
rep(j,0,n+2) b[j] -= a[j] * inv2; } for (int i = rank; i--;) {
return quad(-1, 1, [&](double z) {
b[s] = a[s] * inv2; } b[i] /= A[i][i];
return x*x + y*y + z*z < 1; });});}); 92dd79, 15 lines } return res; x[col[i]] = b[i];
typedef double d; rep(j,0,n+2) if (j != s) D[r][j] *= inv; } rep(j,0,i) b[j] -= A[j][i] * b[i];
#define S(a,b) (f(a) + 4*f((a+b) / 2) + f(b)) rep(i,0,m+2) if (i != r) D[i][s] *= -inv; }
* (b-a) / 6 D[r][s] = inv; return rank; // ( multiple solutions i f rank
swap(B[r], N[s]);
IntDeterminant.h < m)
Description: Calculates determinant using modular
template <class F> } }
arithmetics. Modulos can also be removed to get a pure-
d rec(F& f, d a, d b, d eps, d S) { integer version.
d c = (a + b) / 2; bool simplex(int phase) { Time: O N 3

d S1 = S(a, c), S2 = S(c, b), T = S1 + S2; int x = m + phase - 1; 3313dc, 18 lines SolveLinear2.h
if (abs(T - S) <= 15 * eps || b - a < 1e-10) for (;;) { const ll mod = 12345; Description: To get all uniquely determined values of
return T + (T - S) / 15; int s = -1; ll det(vector<vector<ll>>& a) { x back from SolveLinear, make the following changes:
return rec(f, a, c, eps / 2, S1) + rec(f, c, rep(j,0,n+1) if (N[j] != -phase) ltj(D[x int n = sz(a); ll ans = 1; "SolveLinear.h" 08e495, 7 lines
b, eps / 2, S2); ]); rep(i,0,n) { rep(j,0,n) if (j != i) // instead of rep( j , i
} if (D[x][s] >= -eps) return true; rep(j,i+1,n) { +1,n)
template<class F> int r = -1; while (a[j][i] != 0) { // gcd step // . . . then at the end :
d quad(d a, d b, F f, d eps = 1e-8) { rep(i,0,m) { ll t = a[i][i] / a[j][i]; x.assign(m, undefined);
return rec(f, a, b, eps, S(a, b)); if (D[i][s] <= eps) continue; if (t) rep(k,i,n) rep(i,0,rank) {
BRACU SolveLinearBinary MatrixInverse Tridiagonal FastFourierTransform FastFourierTransformMod NumberTheoreticTransform 7
rep(j,rank,m) if (fabs(A[i][j]) > eps) goto A[i].swap(A[r]); tmp[i].swap(tmp[r]); } }
fail; rep(j,0,n) for (int i = n; i--;) {
x[col[i]] = b[i] / A[i][i]; swap(A[j][i], A[j][c]), swap(tmp[j][i], if (tr[i]) {
fail:; } tmp[j][c]); swap(b[i], b[i-1]); FastFourierTransformMod.h
swap(col[i], col[c]); diag[i-1] = diag[i];
double v = A[i][i]; b[i] /= super[i-1]; Description: Higher precision FFT, can be used for con-
SolveLinearBinary.h rep(j,i+1,n) { } else {
Description: Solves Ax = b over F2 . If there are multi- volutions modulo arbitrary integers as long as N log2 N ·
double f = A[j][i] / v; b[i] /= diag[i];
ple solutions, one is returned arbitrarily. Returns rank, mod < 8.6 · 1014 (in practice 1016 or higher). Inputs
A[j][i] = 0; if (i) b[i-1] -= b[i]*super[i-1];
or -1 if no solutions. Destroys A and b. must be in [0, mod).
rep(k,i+1,n) A[j][k] -= f*A[i][k]; }
Time: O n2 m Time: O (N log N ), where N = |A| + |B| (twice as slow

fa2d7a, 34 lines rep(k,0,n) tmp[j][k] -= f*tmp[i][k]; }
as NTT or FFT)
typedef bitset<1000> bs; } return b;
"FastFourierTransform.h" b82773, 22 lines
rep(j,i+1,n) A[i][j] /= v; }
rep(j,0,n) tmp[i][j] /= v; typedef vector<ll> vl;
int solveLinear(vector<bs>& A, vi& b, bs& x,
template<int M> vl convMod(const vl &a, const
int m) {
}
A[i][i] = 1; 4.4 Fourier transforms vl &b) {
int n = sz(A), rank = 0, br;
assert(m <= sz(x)); FastFourierTransform.h if (a.empty() || b.empty()) return {};
Description: fft(a) computes fˆ(k) = vl res(sz(a) + sz(b) - 1);
P
vi col(m); iota(all(col), 0); for (int i = n-1; i > 0; --i) rep(j,0,i) { x a[x] exp(2πi ·
double v = A[j][i]; kx/N ) for all k. N must be a power of 2. P Useful for int B=32-__builtin_clz(sz(res)), n=1<<B, cut
rep(i,0,n) {
rep(k,0,n) tmp[j][k] -= v*tmp[i][k]; convolution: conv(a, b) = c, where c[x] = a[i]b[x − =int(sqrt(M));
for (br=i; br<n; ++br) if (A[br].any())
} i]. For convolution of complex numbers or more than vector<C> L(n), R(n), outs(n), outl(n);
break;
two vectors: FFT, multiply pointwise, divide by n, re- rep(i,0,sz(a)) L[i] = C((int)a[i] / cut, (
if (br == n) {
verse(start+1, int)a[i] % cut);
rep(j,i,n) if(b[j]) return -1; rep(i,0,n) rep(j,0,n) A[col[i]][col[j]] = P 2 end), FFT back. Rounding is safe if
( a2i + bi ) log2 N < 9 · 1014 (in practice 1016 ; higher rep(i,0,sz(b)) R[i] = C((int)b[i] / cut, (
P
break; tmp[i][j];
return n; for random inputs). Otherwise, use NTT/FFTMod. int)b[i] % cut);
}
int bc = (int)A[br]._Find_next(i-1); } Time: O (N log N ) with N = |A|+|B| (∼1s00ced6,for N = 222 )
35 lines
fft(L), fft(R);
rep(i,0,n) {
swap(A[i], A[br]); typedef complex<double> C; int j = -i & (n - 1);
swap(b[i], b[br]); Tridiagonal.h typedef vector<double> vd; outl[j] = (L[i] + conj(L[j])) * R[i] /
swap(col[i], col[bc]); Description: x = tridiagonal(d, p, q, b) solves the equa- void fft(vector<C>& a) { (2.0 * n);
rep(j,0,n) if (A[j][i] != A[j][bc]) { tion system int n = sz(a), L = 31 - __builtin_clz(n); outs[j] = (L[i] - conj(L[j])) * R[i] /
A[j].flip(i); A[j].flip(bc);   static  vector<complex<long double>> R(2, 1);
b0 d0 p0 0 0 ··· 0 x0 (2.0 * n) / 1i;
  
} vector<C> rt(2, 1); // (^ 10% faster
rep(j,i+1,n) if (A[j][i]) {  b1   q0 d1 p1 0 ··· 0   static
x1  }
 b
2
  0 q1 d2 p2 ··· 0  x
2
i
f double ) fft(outl), fft(outs);
b[j] ^= b[i];     
  forx (static int k = 2; k < n; k *= 2) {
 b
3 = .
 
. .. .. .. . 3 .
 rep(i,0,sz(res)) {
A[j] ^= A[i]; 
 . . .

  R.resize(n); rt.resize(n);

.

 . . . . . . .
 ll av = ll(real(outl[i])+.5), cv = ll(imag
} 
.
 
.

rank++;
 .   0 0 ··· qn−3 dn−2 pn−2   auto . x = polar(1.0L, acos(-1.0L) / k);
 (outs[i])+.5);
} bn−1 0 0 ··· 0 qn−2 dn−1 xrep(i,k,2
n−1
*k) rt[i] = R[i] = i&1 ? R[i/2] * ll bv = ll(imag(outl[i])+.5) + ll(real(
x : R[i/2]; outs[i])+.5);
This is useful for solving problems on the type } res[i] = ((av % M * cut + bv) % M * cut +
x = bs(); vi rev(n);
ai = bi ai−1 + ci ai+1 + di , 1 ≤ i ≤ n, cv) % M;
for (int i = rank; i--;) { rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << }
if (!b[i]) continue; where a0 , an+1 , bi , ci and di are known. a can then be L) / 2; return res;
x[col[i]] = 1; obtained from rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[ }
rep(j,0,i) b[j] ^= A[j][i]; i]]);
} {ai } = tridiagonal({1, −1, −1, ..., −1, 1}, {0, c1 , c2 , . . . , cn },
for (int k = 1; k < n; k *= 2)
return rank; // ( multiple solutions i f rank {b1 , b2 , . . . , bn , 0}, {a0 , d1 , d2 , . . . , dn , an+1 }).
for (int i = 0; i < n; i += 2 * k) rep(j NumberTheoreticTransform.h
< m) ,0,k) {
} Fails if the solution is not unique.
C z = rt[j+k] * a[i+j+k]; // (25% faster
If |di | > |pi | + |qi−1 | for all i, or |di | > |pi−1 | + |qi |, or Description: ntt(a) computes fˆ(k) = xk
P
i f hand=r o l l e d ) x a[x]g for
the matrix is positive definite, the algorithm is numeri- all k, where g = root(mod−1)/N . N must be a power of
MatrixInverse.h cally stable and neither tr nor the check for diag[i] == a[i + j + k] = a[i + j] - z;
a[i + j] += z; 2. Useful for convolution modulo specific nice primes of
Description: Invert matrix A. Returns rank; result is 0 is needed. the form 2a b + 1, where the convolution result has size at
stored in A unless singular (rank < n). Can easily be Time: O (N ) }
8f9fa8, 26 lines } most 2a . For arbitraryPmodulo, see FFTMod. conv(a,
extended to prime moduli; for prime powers, repeatedly b) = c, where c[x] = a[i]b[x − i]. For manual convo-
set A−1 = A−1 (2I − AA−1 ) (mod pk ) where A−1 starts typedef double T; vd conv(const vd& a, const vd& b) {
vector<T> tridiagonal(vector<T> diag, const if (a.empty() || b.empty()) return {}; lution: NTT the inputs, multiply pointwise, divide by n,
as the inverseof A mod p, and k is doubled in each step. reverse(start+1, end), NTT back. Inputs must be in [0,
Time: O n3 vector<T>& super, vd res(sz(a) + sz(b) - 1);
ebfff6, 35 lines const vector<T>& sub, vector<T> b) { int L = 32 - __builtin_clz(sz(res)), n = 1 mod).
int matInv(vector<vector<double>>& A) { int n = sz(b); vi tr(n); << L; Time: O (N log N )
int n = sz(A); vi col(n); rep(i,0,n-1) { vector<C> in(n), out(n); "../number-theory/ModPow.h" ced03d, 33 lines

vector<vector<double>> tmp(n, vector<double if (abs(diag[i]) < 1e-9 * abs(super[i])) { copy(all(a), begin(in)); const ll mod = (119 << 23) + 1, root = 62; //
>(n)); // diag [ i ] == 0 rep(i,0,sz(b)) in[i].imag(b[i]); = 998244353
rep(i,0,n) tmp[i][i] = 1, col[i] = i; b[i+1] -= b[i] * diag[i+1] / super[i]; fft(in); // For p < 2^30 there i s also e . g . 5 << 25, 7
if (i+2 < n) b[i+2] -= b[i] * sub[i+1] / for (C& x : in) x *= x; << 26, 479 << 21
rep(i,0,n) { super[i]; rep(i,0,n) out[i] = in[-i & (n - 1)] - conj( // and 483 << 21 (same root ) . The l a s t two are
int r = i, c = i; diag[i+1] = sub[i]; tr[++i] = 1; in[i]); > 10^9.
rep(j,i,n) rep(k,i,n) } else { fft(out); typedef vector<ll> vl;
if (fabs(A[j][k]) > fabs(A[r][c])) diag[i+1] -= super[i]*sub[i]/diag[i]; rep(i,0,sz(res)) res[i] = imag(out[i]) / (4 void ntt(vl &a) {
r = j, c = k; b[i+1] -= b[i]*sub[i]/diag[i]; * n); int n = sz(a), L = 31 - __builtin_clz(n);
if (fabs(A[r][c]) < 1e-12) return i; } return res; static vl rt(2, 1);
BRACU FastSubsetTransform ModularArithmetic ModInverse ModPow ModLog ModSum ModMulLL ModSqrt FastEratosthenes MillerRabin 8
for (static int k = 2, s = 2; k < n; k *= 2,
s++) {
Number theory (5) return n * i - A[e];
return -1;
ll x = modpow(a, (s + 1) / 2, p);
ll b = modpow(a, s, p), g = modpow(n, s, p);
rt.resize(n); } for (;; r = m) {
ll z[] = {1, modpow(root, mod >> s)}; 5.1 Modular arithmetic ll t = b;
rep(i,k,2*k) rt[i] = rt[i / 2] * z[i & 1] ModularArithmetic.h ModSum.h for (m = 0; m < r && t != 1; ++m)
% mod; Description: Operators for modular arithmetic. You Description: Sums of mod’ed arithmetic progressions. t = t * t % p;
} need to set mod to some number first and then you can modsum(to, c, k, m) =
Pto−1 if (m == 0) return x;
i=0 (ki + c)%m. divsum is
vi rev(n); use the structure. similar but for floored division. ll gs = modpow(g, 1LL << (r - m - 1), p);
rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << "euclid.h" 35bfea, 18 lines Time: log(m), with a large constant. g = gs * gs % p;
L) / 2; 5c5bc5, 16 lines x = x * gs % p;
const ll mod = 17; // change to something e l s e typedef unsigned long long ull;
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[ b = b * g % p;
struct Mod { ull sumsq(ull to) { return to / 2 * ((to-1) |
i]]); }
ll x; 1); }
for (int k = 1; k < n; k *= 2) }
Mod(ll xx) : x(xx) {}
for (int i = 0; i < n; i += 2 * k) rep(j
Mod operator+(Mod b) { return Mod((x + b.x) ull divsum(ull to, ull c, ull k, ull m) {
,0,k) {
ll z = rt[j + k] * a[i + j + k] % mod, &
% mod); } ull res = k / m * sumsq(to) + c / m * to; 5.2 Primality
Mod operator-(Mod b) { return Mod((x - b.x +
ai = a[i + j];
mod) % mod); }
k %= m; c %= m; FastEratosthenes.h
a[i + j + k] = ai - z + (z > ai ? mod : if (!k) return res; Description: Prime sieve for generating all primes
Mod operator*(Mod b) { return Mod((x * b.x) ull to2 = (to * k + c) / m;
0); smaller than LIM.
% mod); } return res + (to - 1) * to2 - divsum(to2, m
ai += (ai + z >= mod ? z - mod : z); Time: LIM=1e9 ≈ 1.5s
Mod operator/(Mod b) { return *this * invert -1 - c, m, k); 6b2912, 20 lines
}
(b); } } const int LIM = 1e6;
}
Mod invert(Mod a) { bitset<LIM> isPrime;
vl conv(const vl &a, const vl &b) {
ll x, y, g = euclid(a.x, mod, x, y); ll modsum(ull to, ll c, ll k, ll m) { vi eratosthenes() {
if (a.empty() || b.empty()) return {};
assert(g == 1); return Mod((x + mod) % mod c = ((c % m) + m) % m; const int S = (int)round(sqrt(LIM)), R = LIM
int s = sz(a) + sz(b) - 1, B = 32 -
); k = ((k % m) + m) % m; / 2;
__builtin_clz(s), n = 1 << B;
} return to * c + k * sumsq(to) - m * divsum( vi pr = {2}, sieve(S+1); pr.reserve(int(LIM/
int inv = modpow(n, mod - 2);
Mod operator^(ll e) { to, c, k, m); log(LIM)*1.1));
vl L(a), R(b), out(n);
if (!e) return Mod(1); } vector<pii> cp;
L.resize(n), R.resize(n);
Mod r = *this ^ (e / 2); r = r * r; for (int i = 3; i <= S; i += 2) if (!sieve[i
ntt(L), ntt(R);
return e&1 ? *this * r : r; ]) {
rep(i,0,n) out[-i & (n - 1)] = (ll)L[i] * R[ ModMulLL.h
} cp.push_back({i, i * i / 2});
i] % mod * inv % mod; Description: Calculate a · b mod c (or ab mod c) for
}; for (int j = i * i; j <= S; j += 2 * i)
ntt(out); 0 ≤ a, b ≤ c ≤ 7.2 · 1018 .
return {out.begin(), out.begin() + s}; sieve[j] = 1;
Time: O (1) for modmul, O (log b) for modpow
} ModInverse.h bbbd8f, 11 lines }
Description: Pre-computation of modular inverses. As- typedef unsigned long long ull; for (int L = 1; L <= R; L += S) {
sumes LIM ≤ mod and that mod is a prime.6f684f, 3 lines ull modmul(ull a, ull b, ull M) { array<bool, S> block{};
ll ret = a * b - M * ull(1.L / M * a * b); for (auto &[p, idx] : cp)
const ll mod = 1000000007, LIM = 200000; return ret + M * (ret < 0) - M * (ret >= (ll for (int i=idx; i < S+L; idx = (i+=p))
FastSubsetTransform.h ll* inv = new ll[LIM] - 1; inv[1] = 1; )M); block[i-L] = 1;
Description: TransformX to a basis with fast convolu- rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[ } rep(i,0,min(S, R - L))
mod % i] % mod; if (!block[i]) pr.push_back((L + i) * 2
tions of the form c[z] = a[x] · b[y], where ⊕ is ull modpow(ull b, ull e, ull mod) {
z=x⊕y + 1);
one of AND, OR, XOR. The size of a must be a power ull ans = 1;
of two.
ModPow.h b83e45, 8 lines
for (; e; b = modmul(b, b, mod), e /= 2) }
if (e & 1) ans = modmul(ans, b, mod); for (int i : pr) isPrime[i] = 1;
Time: O (N log N ) 464cf3, 16 lines const ll mod = 1000000007; // f a st e r i f const return pr;
return ans;
void FST(vi& a, bool inv) { } }
ll modpow(ll b, ll e) {
for (int n = sz(a), step = 1; step < n; step
ll ans = 1;
*= 2) { for (; e; b = b * b % mod, e /= 2) ModSqrt.h MillerRabin.h
for (int i = 0; i < n; i += 2 * step) rep( Description: Tonelli-Shanks algorithm for modular Description: Deterministic Miller-Rabin primality test.
if (e & 1) ans = ans * b % mod;
j,i,i+step) { square roots. Finds x s.t. x2 = a (mod p) (−x gives Guaranteed to work for numbers up to 7 · 1018 ; for larger
return ans;
int &u = a[j], &v = a[j + step]; tie(u, the other solution). numbers, use Python and extend A randomly.
}
v) = Time: O log2 p worst case, O (log p) for most p

Time: 7 times the complexity of ab mod c.
inv ? pii(v - u, u) : pii(v, u + v); "ModPow.h" 19a793, 24 lines "ModMulLL.h" 60dcd1, 12 lines
// AND ModLog.h x ll sqrt(ll a, ll p) { bool isPrime(ull n) {
inv ? pii(v, u - v) : pii(u + v, u); Description: Returns the smallest x > 0 s.t. a = b
(mod m), or −1 if no such x exists. modLog(a,1,m) can a %= p; if (a < 0) a += p; if (n < 2 || n % 6 % 4 != 1) return (n | 1)
// OR
be used to √
calculate the order of a. if (a == 0) return 0; == 3;
pii(u + v, u - v);
Time: O m
 assert(modpow(a, (p-1)/2, p) == 1); // e l s e ull A[] = {2, 325, 9375, 28178, 450775,
// XOR c040b8, 11 lines no solution 9780504, 1795265022},
}
ll modLog(ll a, ll b, ll m) { if (p % 4 == 3) return modpow(a, (p+1)/4, p) s = __builtin_ctzll(n-1), d = n >> s;
}
ll n = (ll) sqrt(m) + 1, e = 1, f = 1, j = ; for (ull a : A) { // ^ count t r a i l i n g
if (inv) for (int& x : a) x /= sz(a); // XOR
1; // a^(n+3)/8 or 2^(n+3)/8 * 2^(n=1)/4 works zeroes
only
unordered_map<ll, ll> A; i f p % 8 == 5 ull p = modpow(a%n, d, n), i = s;
}
while (j <= n && (e = f = e * a % m) != b % ll s = p - 1, n = 2; while (p != 1 && p != n - 1 && a % n && i
vi conv(vi a, vi b) {
m) int r = 0, m; --)
FST(a, 0); FST(b, 0);
A[e * b % m] = j++; while (s % 2 == 0) p = modmul(p, p, n);
rep(i,0,sz(a)) a[i] *= b[i];
if (e == b % m) return j; ++r, s /= 2; if (p != n-1 && i != s) return 0;
FST(a, 1); return a;
if (__gcd(m, e) == __gcd(m, b)) while (modpow(n, (p - 1) / 2, p) != p - 1) }
}
rep(i,2,n+2) if (A.count(e = e * f % m)) ++n; return 1;
BRACU Factor euclid CRT phiFunction ContinuedFractions FracBinarySearch IntPerm 9
} If (x, y) is one solution, then all solutions are FracBinarySearch.h The number of divisors of n is at most around
given by Description: Given f and N , finds the smallest fraction 100 for n < 5e4, 500 for n < 1e7, 2000 for
p/q ∈ [0, 1] such that f (p/q) is true, and p, q ≤ N . You
Factor.h   may want to throw an exception from f if it finds an ex- n < 1e10, 200 000 for n < 1e19.
kb ka act solution, in which case N can be removed.
Description: Pollard-rho randomized factorization al- x+ ,y − , k∈Z 5.8 Mobius Function
gorithm. Returns prime factors of a number, in arbitrary gcd(a, b) gcd(a, b) Usage: fracBS([](Frac f) { return f.p>=3*f.q; 
}, 10); // {1,3}
order (e.g. 2299-> {11, 19, 11}).
Time: O (log(N ))
0
 n is not square free
Time: O n1/4 , less for numbers with small factors. 27ab3e, 25 lines
µ(n) = 1 n has even number of prime factors
"ModMulLL.h", "MillerRabin.h" a33cf6, 18 lines
phiFunction.h struct Frac { ll p, q; };
Description: Euler’s ϕ function is defined as ϕ(n) :=

−1 n has odd number of prime factors

ull pollard(ull n) { # of positive integers ≤ n that are coprime with n.
auto f = [n](ull x) { return modmul(x, x, n) ϕ(1) = 1, p prime ⇒ ϕ(pk ) = (p − 1)pk−1 , m, n coprime template<class F>
+ 1; }; k k Frac fracBS(F f, ll N) { Mobius Inversion:
⇒ ϕ(mn) = ϕ(m)ϕ(n). If n = p1 1 p2 2 ...pk r
r then ϕ(n) = bool dir = 1, A = 1, B = 1; X X
ull x = 0, y = 0, t = 30, prd = 2, i = 1, q;
while (t++ % 40 || __gcd(prd, n) == 1) {
k −1
(p1 − 1)p1 1 ...(pr − 1)pk
r
r −1 . ϕ(n) = n ·
Q
p|n (1 − 1/p). Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to g(n) = f (d) ⇔ f (n) = µ(d)g(n/d)
search (0 , N]
P P
if (x == y) x = ++i, y = f(x); d|n ϕ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nϕ(n)/2, n > 1
d|n d|n
if ((q = modmul(prd, max(x,y) - min(x,y), if (f(lo)) return lo;
Euler’s thm: a, n coprime ⇒ aϕ(n) ≡ 1 (mod n).
n))) prd = q; assert(f(hi)); Other useful formulas/forms:
Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 cf7d6d,
(mod p) ∀a. while (A || B) {
x = f(x), y = f(f(y)); 8 lines P
ll adv = 0, step = 1; // move hi i f dir ,
} const int LIM = 5000000; d|n µ(d) = [n = 1] (very useful)
return __gcd(prd, n); int phi[LIM]; e l s e lo
for (int si = 0; step; (step *= 2) >>= si)
P
} g(n) = n|d f (d) ⇔ f (n) =
vector<ull> factor(ull n) { void calculatePhi() { { P
if (n == 1) return {}; rep(i,0,LIM) phi[i] = i&1 ? i : i/2; adv += step; n|d µ(d/n)g(d)
if (isPrime(n)) return {n}; for (int i = 3; i < LIM; i += 2) if(phi[i] Frac mid{lo.p * adv + hi.p, lo.q * adv + P n
ull x = pollard(n); == i) hi.q}; g(n) = 1≤m≤n f ( m ) ⇔ f (n) =
auto l = factor(x), r = factor(n / x); for (int j = i; j < LIM; j += i) phi[j] -= if (abs(mid.p) > N || mid.q > N || dir P n
l.insert(l.end(), all(r)); phi[j] / i; == !f(mid)) { 1≤m≤n µ(m)g( m )
return l; } adv -= step; si = 2;
}
}
}
Combinatorial (6)
5.4 Fractions hi.p += lo.p * adv;
ContinuedFractions.h hi.q += lo.q * adv; 6.1 Permutations
5.3 Divisibility Description: Given N and a real number x ≥ 0, finds dir = !dir;
the closest rational approximation p/q with p, q ≤ N . It swap(lo, hi); 6.1.1 Factorial
euclid.h A = B; B = !!adv;
Description: Finds two integers x and y, such that will obey |p/q − x| ≤ 1/qN .
For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . }
ax + by = gcd(a, b). If you just need gcd, use the built n 123 4 5 6 7 8 9 10
(pk /qk alternates between > x and < x.) If x is ratio- return dir ? hi : lo;
in gcd instead. If a and b are coprime, then x is the
nal, y eventually becomes ∞; if x is the root of a degree } n! 1 2 6 24 120 720 5040 40320 362880 3628800
inverse of a (mod b). 33ba8f, 5 lines
2 polynomial the a’s eventually become cyclic. n 11 12 13 14 15 16 17
ll euclid(ll a, ll b, ll &x, ll &y) { Time: O (log N ) dd6c5e, 21 lines 5.5 Pythagorean Triples
if (!b) return x = 1, y = 0, a; n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14
ll d = euclid(b, a % b, y, x); typedef double d; // for N ∼ 1e7 ; long double The Pythagorean triples are uniquely generated n 20 25 30 40 50 100 150 17
return y -= a/b * x, d; for N ∼ 1e9 by
} pair<ll, ll> approximate(d x, ll N) { n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL
ll LP = 0, LQ = 1, P = 1, Q = 0, inf =
LLONG_MAX; d y = x; a = k ·(m2 −n2 ), b = k ·(2mn), c = k ·(m2 +n2 ), IntPerm.h
CRT.h for (;;) { Description: Permutation -> integer conversion. (Not
Description: Chinese Remainder Theorem. ll lim = min(P ? (N-LP) / P : inf, Q ? (N- order preserving.) Integer -> permutation can use a
LQ) / Q : inf),
with m > n > 0, k > 0, m⊥n, and either m or n
crt(a, m, b, n) computes x such that x ≡ a (mod m), lookup table.
x ≡ b (mod n). If |a| < m and |b| < n, x will obey a = (ll)floor(y), b = min(a, lim), even. Time: O (n) 044568, 6 lines
0 ≤ x < lcm(m, n). Assumes mn < 262 . NP = b*P + LP, NQ = b*Q + LQ;
Time: log(n) if (a > b) { 5.6 Primes int permToInt(vi& v) {
// I f b > a/2, we have a semi=convergent 21
int use = 0, i = 0, r = 0;
"euclid.h" 04d93a, 7 lines
that gives us a
p = 962592769 is such that 2 | p − 1, which for(int x:v) r = r * ++i +
ll crt(ll a, ll m, ll b, ll n) { may be useful. For hashing use 970592641 __builtin_popcount(use & -(1<<x)),
// better approximation ; i f b = a/2, we
if (n > m) swap(a, b), swap(m, n);
*may* have one . (31-bit number), 31443539979727 (45-bit),
use |= 1 << x; // (
ll x, y, g = euclid(m, n, x, y); note : minus, not ∼! )
// Return {P, Q} here for a more
assert((a - b) % g == 0); // e l s e no
canonical approximation . 3006703054056749 (52-bit). There are 78498 return r;
solution }
x = (b - a) % n * x % n / g * m + a;
return (abs(x - (d)NP / (d)NQ) < abs(x - primes less than 1 000 000.
(d)P / (d)Q)) ?
return x < 0 ? x + m*n/g : x;
}
make_pair(NP, NQ) : make_pair(P, Q); Primitive roots exist modulo any prime power 6.1.2 Cycles
5.3.1 Bézout’s identity }
pa , except for p = 2, a > 2, and there are Let gS (n) be the number of n-permutations
if (abs(y = 1/(y - (d)a)) > 3*N) {
For a ̸=, b ̸= 0, then d = gcd(a, b) is the smallest return {NP, NQ}; ϕ(ϕ(pa )) many. For p = 2, a > 2, the group Z×
2a whose cycle lengths all belong to the set S.
positive integer for which there are integer } is instead isomorphic to Z2 × Z2a−2 . Then
LP = P; P = NP;
solutions to ∞
!
LQ = Q; Q = NQ;
5.7 Estimates X xn X xn
} gS (n) = exp
n! n
P
ax + by = d } d|n d = O(n log log n). n=0 n∈S
BRACU multinomial BellmanFord FloydWarshall TopoSort 10
6.1.3 Derangements c = c * ++m / (j+1); S(n, 1) = S(n, n) = 1 const ll inf = LLONG_MAX;
return c; struct Ed { int a, b, w, s() { return a < b ?
Permutations of a set such that none of the } k
!
a : -a; }};
1 X k n
elements appear in their original S(n, k) = (−1)k−j j struct Node { ll dist = inf; int prev = -1; };
position. 6.3 General purpose k! j=0
j
void bellmanFord(vector<Node>& nodes, vector<
 numbers
 Ed>& eds, int s) {
n n! 6.3.5 Bell numbers
D(n) = (n−1)(D(n−1)+D(n−2)) = nD(n−1)+(−1) =
6.3.1
nodes[s].dist = 0;
eBernoulli numbers Total number of partitions of n distinct sort(all(eds), [](Ed a, Ed b) { return a.s()
EGF of Bernoulli numbers is B(t) = et t−1 elements. B(n) =
< b.s(); });
6.1.4 Burnside’s lemma (FFT-able). 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, . . . . For p int lim = sz(nodes) / 2 + 2; // /3+100 with
Given a group G of symmetries and a set X, the B[0, . . .] = [1, − 21 , 16 , 0, − 30
1 1
, 0, 42 , . . .] prime, shuffled vertices
rep(i,0,lim) for (Ed ed : eds) {
number of elements of X up to symmetry Sums of powers: Node cur = nodes[ed.a], &dest = nodes[ed.b
equals n m 
B(pm + n) ≡ mB(n) + B(n + 1) (mod p) ];
1 X g
X
m 1 X m + 1
|X |, n = Bk · (n + 1)m+1−k if (abs(cur.dist) == inf) continue;
|G| g∈G m + 1 k=0 k ll d = cur.dist + ed.w;
i=1 6.3.6 Labeled unrooted trees if (d < dest.dist) {
# on n vertices: nn−2 dest.prev = ed.a;
where X g are the elements fixed by g Euler-Maclaurin formula for infinite dest.dist = (i < lim-1 ? d : -inf);
sums: # on k existing trees of size ni : }
(g.x = x).
∞ Z ∞ ∞ n1 n2 · · · nk nk−2 }
X X Bk (k−1)
If f (n) counts “configurations” (of some sort) of f (i) = f (x)dx − f (m) # with degrees di : rep(i,0,lim) for (Ed e : eds) {
m k! if (nodes[e.a].dist == -inf)
length n, we can ignore rotational symmetry i=m k=1 (n − 2)!/((d1 − 1)! · · · (dn − 1)!) nodes[e.b].dist = -inf;
Z ∞ f (m) f ′ (m) f ′′′ (m)
using G = Zn to get }
≈ f (x)dx+ − + +O(f (5) (m)) 6.3.7 Catalan numbers }
m 2 12 720
n−1
1 X 1X
g(n) = f (gcd(n, k)) = f (k)ϕ(n/k). 6.3.2 Stirling numbers of the first ! ! !
n
k=0
n
k|n kind 1 2n 2n 2n (2n)! FloydWarshall.h
Cn = = − = Description: Calculates all-pairs shortest path in a di-
Number of permutations on n items with k n+1 n n n+1 (n + 1)!n! rected graph that might have negative edge weights. In-
6.2 Partitions and subsets cycles. put is an distance matrix m, where m[i][j] = inf if i and
j are not adjacent. As output, m[i][j] is set to the short-
2(2n + 1) X
6.2.1 Partition function c(n, k) = c(n − 1, k − 1) + (n − 1)c(n − 1, k), c(0, 0)C=0 = 1, Cn+1 =
1 Cn , Cn+1 = Ci Cn−i est distance between i and j, inf if no path, or -inf if
n+2 the path goes through a negative-weight cycle.
Number of ways of writing n as a sum of Pn Time: O N 3
k
positive integers, disregarding the order of the k=0 c(n, k)x = x(x + 1) . . . (x + n − 1) C n = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, ... 531245, 12 lines

const ll inf = 1LL << 62;


summands. c(8, k) = ˆ sub-diagonal monotone paths in an n × n void floydWarshall(vector<vector<ll>>& m) {
X k+1 8, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1 grid. int n = sz(m);
p(0) = 1, p(n) = (−1) p(n − k(3k − 1)/2) rep(i,0,n) m[i][i] = min(m[i][i], 0LL);
c(n, 2) = ˆ strings with n pairs of parenthesis, rep(k,0,n) rep(i,0,n) rep(j,0,n)
k∈Z\{0}
0, 0, 1, 3, 11, 50, 274, 1764, 13068, 109584, . . . correctly nested. if (m[i][k] != inf && m[k][j] != inf) {
√ ˆ binary trees with with n + 1 leaves (0 or 2 auto newDist = max(m[i][k] + m[k][j], -
p(n) ∼ 0.145/n · exp(2.56 n) 6.3.3 Eulerian numbers inf);
children). m[i][j] = min(m[i][j], newDist);
Number of permutations π ∈ Sn in which ˆ ordered trees with n + 1 vertices. }
n 0 1 2 3 4 5 6 7 8 9 20 50 100 exactly k elements are greater than the previous ˆ ways a convex polygon with n + 2 sides rep(k,0,n) if (m[k][k] < 0) rep(i,0,n) rep(j
p(n) 1 1 2 3 5 7 11 15 22 30 627 ∼2e5 ∼2e8 element. k j:s s.t. π(j) > π(j + 1), k + 1 j:s s.t. can be cut into triangles by connecting
,0,n)
if (m[i][k] != inf && m[k][j] != inf) m[i
6.2.2 Lucas’ Theorem π(j) ≥ j, k j:s s.t. π(j) > j. vertices with straight lines. ][j] = -inf;
}
Let n, m be non-negative integers and p a prime. E(n, k) = (n−k)E(n−1, k−1)+(k+1)E(n−1, k) ˆ permutations of [n] with no 3-term
Write n = nk pk + ... + n1 p + n0 and increasing subseq.
m= k E(n, 0) = E(n, n − 1) = 1 TopoSort.h
 mQk p + ... +
 m1 p + m0 . Then Description: Topological sorting. Given is an oriented
n k ni
Graph (7)
k
!
m
≡ i=0 mi
(mod p). X j n+1 graph. Output is an ordering of vertices, such that there
E(n, k) = (−1) (k + 1 − j)n are edges only from left to right. If there are cycles, the
6.2.3 Binomials j
j=0 7.1 Fundamentals returned list will have size smaller than n – nodes reach-
multinomial.h able from cycles will not be returned.
k + · · · + k 
1 n 6.3.4 Stirling numbers of the second BellmanFord.h Time: O (|V | + |E|)
Description: Computes = Description: Calculates shortest paths from s in a 66a137, 14 lines
k1 , k2 , . . . , kn
P
( ki )! kind graph that might have negative edge weights. Un- vi topoSort(const vector<vi>& gr) {
. reachable nodes get dist = inf; nodes reachable through vi indeg(sz(gr)), ret;
k1 !k2 !...kn ! a0a312, 6 lines Partitions of n distinct elements into exactly k negative-weight cycles get dist = -inf. Assumes for (auto& li : gr) for (int x : li) indeg[x
ll multinomial(vi& v) { groups. V 2 max |wi | < ∼263 . ]++;
ll c = 1, m = v.empty() ? 1 : v[0]; Time: O (V E) queue<int> q; // use priority queue for
830a8f, 23 lines
rep(i,1,sz(v)) rep(j,0,v[i]) S(n, k) = S(n − 1, k − 1) + kS(n − 1, k) l e x i c . l a r g e s t ans .
BRACU PushRelabel MinCostMaxFlow EdmondsKarp MinCut GlobalMinCut GomoryHu 11
rep(i,0,sz(gr)) if (indeg[i] == 0) q.push(i) --co[H[i]], H[i] = v + 1; for (auto e : graph[x]) {
; hi = H[u]; while (!q.empty()) { if (par[e.first] == -1 && e.second >
while (!q.empty()) { } else if (cur[u]->c && H[u] == H[cur[ s = q.top().second; q.pop(); 0) {
int i = q.front(); // top () for priority u]->dest]+1) seen[s] = 1; di = dist[s] + pi[s]; par[e.first] = x;
queue addFlow(*cur[u], min(ec[u], cur[u]-> for (int i : ed[s]) if (!seen[i]) q[ptr++] = e.first;
ret.push_back(i); c)); relax(i, cap[s][i] - flow[s][i], cost[ if (e.first == sink) goto out;
q.pop(); else ++cur[u]; s][i], 1); }
for (int x : gr[i]) } for (int i : red[s]) if (!seen[i]) }
if (--indeg[x] == 0) q.push(x); } relax(i, flow[i][s], -cost[i][s], 0); }
} bool leftOfMinCut(int a) { return H[a] >= sz } return flow;
return ret; (g); } rep(i,0,N) pi[i] = min(pi[i] + dist[i], out:
} }; INF); T inc = numeric_limits<T>::max();
} for (int y = sink; y != source; y = par[y
])
7.2 Network flow MinCostMaxFlow.h pair<ll, ll> maxflow(int s, int t) { inc = min(inc, graph[par[y]][y]);
Description: Min-cost max-flow. cap[i][j] != cap[j][i] is ll totflow = 0, totcost = 0;
PushRelabel.h allowed; double edges are not. If costs can be negative, while (path(s), seen[t]) { flow += inc;
Description: Push-relabel using the highest label selec- call setpi before maxflow, but note that negative cost cy- ll fl = INF; for (int y = sink; y != source; y = par[y
tion rule and the gap heuristic. Quite fast in practice. cles are not supported. To obtain the actual flow, look for (int p,r,x = t; tie(p,r) = par[x], x ]) {
To obtain the actual flow, look at positive values only. at positive values only.
√  != s; x = p) int p = par[y];
Time: O V 2 E Time: Approximately O E 2

0ae1d4, 48 lines fe85cc, 81 lines
fl = min(fl, r ? cap[p][x] - flow[p][x if ((graph[p][y] -= inc) <= 0) graph[p].
] : flow[x][p]); erase(y);
struct PushRelabel { #include <bits/extc++.h> totflow += fl; graph[y][p] += inc;
struct Edge { for (int p,r,x = t; tie(p,r) = par[x], x }
int dest, back; const ll INF = numeric_limits<ll>::max() / 4; != s; x = p) }
ll f, c; typedef vector<ll> VL; if (r) flow[p][x] += fl; }
}; else flow[x][p] -= fl;
vector<vector<Edge>> g; struct MCMF { }
vector<ll> ec; int N; rep(i,0,N) rep(j,0,N) totcost += cost[i][j MinCut.h
vector<Edge*> cur; vector<vi> ed, red; ] * flow[i][j]; Description: After running max-flow, the left side of a
vector<vi> hs; vi H; vector<VL> cap, flow, cost; return {totflow, totcost}; min-cut from s to t is given by all vertices reachable from
PushRelabel(int n) : g(n), ec(n), cur(n), hs vi seen; } s, only traversing edges with positive residual capacity.
(2*n), H(n) {} VL dist, pi;
vector<pii> par; // I f some costs can be negative , c a l l t h i s
void addEdge(int s, int t, ll cap, ll rcap before maxflow :
=0) { MCMF(int N) : GlobalMinCut.h
void setpi(int s) { // ( otherwise , leave Description: Find a global minimum cut in an undi-
if (s == t) return; N(N), ed(N), red(N), cap(N, VL(N)), flow( t h i s out)
g[s].push_back({t, sz(g[t]), 0, cap}); cap), cost(cap), rected graph, as represented by an adjacency matrix.
fill(all(pi), INF); pi[s] = 0; Time: O V 3
g[t].push_back({s, sz(g[s])-1, 0, rcap}); seen(N), dist(N), pi(N), par(N) {} int it = N, ch = 1; ll v; 8b0e19, 21 lines
} while (ch-- && it--) pair<int, vi> globalMinCut(vector<vi> mat) {
void addEdge(int from, int to, ll cap, ll rep(i,0,N) if (pi[i] != INF) pair<int, vi> best = {INT_MAX, {}};
void addFlow(Edge& e, ll f) { cost) { for (int to : ed[i]) if (cap[i][to]) int n = sz(mat);
Edge &back = g[e.dest][e.back]; this->cap[from][to] = cap; if ((v = pi[i] + cost[i][to]) < pi[ vector<vi> co(n);
if (!ec[e.dest] && f) hs[H[e.dest]]. this->cost[from][to] = cost; to]) rep(i,0,n) co[i] = {i};
push_back(e.dest); ed[from].push_back(to); pi[to] = v, ch = 1; rep(ph,1,n) {
e.f += f; e.c -= f; ec[e.dest] += f; red[to].push_back(from); assert(it >= 0); // negative cost cycle vi w = mat[0];
back.f -= f; back.c += f; ec[back.dest] -= } } size_t s = 0, t = 0;
f; }; rep(it,0,n-ph) { // O(V^2) => O(E log V)
} void path(int s) { with prio . queue
ll calc(int s, int t) { fill(all(seen), 0); w[t] = INT_MIN;
int v = sz(g); H[s] = v; ec[t] = 1; fill(all(dist), INF); EdmondsKarp.h s = t, t = max_element(all(w)) - w.begin
vi co(2*v); co[0] = v-1; dist[s] = 0; ll di; Description: Flow algorithm with guaranteed complex- ();
rep(i,0,v) cur[i] = g[i].data(); ity O(V E 2 ). To get edge flow values, compare capacities rep(i,0,n) w[i] += mat[t][i];
for (Edge& e : g[s]) addFlow(e, e.c); __gnu_pbds::priority_queue<pair<ll, int>> before and after, and take the positive values only. }
q; 482fe0, 35 lines
best = min(best, {w[t] - mat[t][t], co[t]}
for (int hi = 0;;) { vector<decltype(q)::point_iterator> its(N) template<class T> T edmondsKarp(vector< );
while (hs[hi].empty()) if (!hi--) return ; unordered_map<int, T>>& graph, int source, co[s].insert(co[s].end(), all(co[t]));
-ec[s]; q.push({0, s}); int sink) { rep(i,0,n) mat[s][i] += mat[t][i];
int u = hs[hi].back(); hs[hi].pop_back() assert(source != sink); rep(i,0,n) mat[i][s] = mat[s][i];
; auto relax = [&](int i, ll cap, ll cost, T flow = 0; mat[0][t] = INT_MIN;
while (ec[u] > 0) // discharge u int dir) { vi par(sz(graph)), q = par; }
if (cur[u] == g[u].data() + sz(g[u])) ll val = di - pi[i] + cost; return best;
{ if (cap && val < dist[i]) { for (;;) { }
H[u] = 1e9; dist[i] = val; fill(all(par), -1);
for (Edge& e : g[u]) if (e.c && H[u] par[i] = {s, dir}; par[source] = 0;
> H[e.dest]+1) if (its[i] == q.end()) its[i] = q.push int ptr = 1; GomoryHu.h
H[u] = H[e.dest]+1, cur[u] = &e; ({-dist[i], i}); q[0] = source; Description: Given a list of edges representing an undi-
if (++co[H[u]], !--co[hi] && hi < v) else q.modify(its[i], {-dist[i], i}); rected flow graph, returns edges of the Gomory-Hu tree.
rep(i,0,v) if (hi < H[i] && H[i] < } rep(i,0,ptr) { The max flow between any pair of vertices is given by
v) }; int x = q[i]; minimum edge weight along the Gomory-Hu tree path.
BRACU hopcroftKarp DFSMatching MinimumVertexCover WeightedMatching GeneralMatching SCC 12
Time: O (V ) Flow Computations if (next.empty()) return res; rep(i,0,m) if (seen[i]) cover.push_back(n+i) assert(r % 2 == 0);
"PushRelabel.h" 0418b3, 13 lines for (int a : next) A[a] = lay; ;
typedef array<ll, 3> Edge; cur.swap(next); assert(sz(cover) == res); if (M != N) do {
vector<Edge> gomoryHu(int N, vector<Edge> ed) } return cover; mat.resize(M, vector<ll>(M));
{ rep(a,0,sz(g)) } rep(i,0,N) {
vector<Edge> tree; res += dfs(a, 0, g, btoa, A, B); mat[i].resize(M);
vi par(N); } WeightedMatching.h rep(j,N,M) {
rep(i,1,N) { } Description: Given a weighted bipartite graph, matches int r = rand() % mod;
PushRelabel D(N); // Dinic also works every node on the left with a node on the right such that mat[i][j] = r, mat[j][i] = (mod - r) %
for (Edge t : ed) D.addEdge(t[0], t[1], t no nodes are in two matchings and the sum of the edge mod;
[2], t[2]); DFSMatching.h weights is minimal. Takes cost[N][M], where cost[i][j] = }
tree.push_back({i, par[i], D.calc(i, par[i Description: Simple bipartite matching algorithm. }
cost for L[i] to be matched with R[j] and returns (min
])}); Graph g should be a list of neighbors of the left partition, } while (matInv(A = mat) != M);
cost, match), where L[i] is matched with R[match[i]].
and btoa should be a vector full of -1’s of the same size
rep(j,i+1,N) Negate costs for max cost. Requires N ≤ M .
as the right partition. Returns the size of the matching. vi has(M, 1); vector<pii> ret;
if (par[j] == par[i] && D.leftOfMinCut(j Time: O N 2 M
)) par[j] = i; btoa[i] will be the match for vertex i on the right side, or 1e0fe9, 31 lines rep(it,0,M/2) {
} −1 if it’s not matched. pair<int, vi> hungarian(const vector<vi> &a) { rep(i,0,M) if (has[i])
return tree; Usage: vi btoa(m, -1); dfsMatching(g, btoa); if (a.empty()) return {0, {}}; rep(j,i+1,M) if (A[i][j] && mat[i][j]) {
} Time: O (V E) 522b98, 22 lines int n = sz(a) + 1, m = sz(a[0]) + 1; fi = i; fj = j; goto done;
vi u(n), v(m), p(m), ans(n - 1); } assert(0); done:
bool find(int j, vector<vi>& g, vi& btoa, vi&
rep(i,1,n) { if (fj < N) ret.emplace_back(fi, fj);
7.3 Matching vis) {
if (btoa[j] == -1) return 1;
p[0] = i; has[fi] = has[fj] = 0;
int j0 = 0; // add ”dummy” worker 0 rep(sw,0,2) {
hopcroftKarp.h vis[j] = 1; int di = btoa[j];
vi dist(m, INT_MAX), pre(m, -1); ll a = modpow(A[fi][fj], mod-2);
Description: Fast bipartite matching algorithm. Graph for (int e : g[di])
vector<bool> done(m + 1); rep(i,0,M) if (has[i] && A[i][fj]) {
g should be a list of neighbors of the left partition, and if (!vis[e] && find(e, g, btoa, vis)) {
do { // d i j k s t r a ll b = A[i][fj] * a % mod;
btoa should be a vector full of -1’s of the same size as the btoa[e] = di;
done[j0] = true; rep(j,0,M) A[i][j] = (A[i][j] - A[fi][
right partition. Returns the size of the matching. btoa[i] return 1;
int i0 = p[j0], j1, delta = INT_MAX; j] * b) % mod;
will be the match for vertex i on the right side, or −1 if }
rep(j,1,m) if (!done[j]) { }
it’s not matched. return 0;
auto cur = a[i0 - 1][j - 1] - u[i0] - swap(fi,fj);
Usage: vi √ btoa(m, -1); hopcroftKarp(g, btoa); }
 v[j]; }
Time: O VE int dfsMatching(vector<vi>& g, vi& btoa) {
f612e4, 42 lines
if (cur < dist[j]) dist[j] = cur, pre[ }
vi vis;
j] = j0; return ret;
bool dfs(int a, int L, vector<vi>& g, vi& btoa rep(i,0,sz(g)) {
if (dist[j] < delta) delta = dist[j], }
, vi& A, vi& B) { vis.assign(sz(btoa), 0);
j1 = j;
if (A[a] != L) return 0; for (int j : g[i])
A[a] = -1; if (find(j, g, btoa, vis)) {
}
rep(j,0,m) {
7.4 DFS algorithms
for (int b : g[a]) if (B[b] == L + 1) { btoa[j] = i;
B[b] = 0; break;
if (done[j]) u[p[j]] += delta, v[j] -= SCC.h
delta; Description: Finds strongly connected components in a
if (btoa[b] == -1 || dfs(btoa[b], L + 1, g }
else dist[j] -= delta; directed graph. If vertices u, v belong to the same com-
, btoa, A, B)) }
} ponent, we can reach u from v and vice versa.
return btoa[b] = a, 1; return sz(btoa) - (int)count(all(btoa), -1);
j0 = j1; Usage: scc(graph, [&](vi& v) { ... }) visits
} }
} while (p[j0]); all components
return 0; while (j0) { // update alternating path in reverse topological order. comp[i] holds
} int j1 = pre[j0]; the component
MinimumVertexCover.h index of a node (a component only has edges to
Description: Finds a minimum vertex cover in a bipar- p[j0] = p[j1], j0 = j1;
int hopcroftKarp(vector<vi>& g, vi& btoa) { } components with
int res = 0; tite graph. The size is the same as the size of a maximum
matching, and the complement is a maximum indepen- } lower index). ncomps will contain the number
vi A(g.size()), B(btoa.size()), cur, next; rep(j,1,m) if (p[j]) ans[p[j] - 1] = j - 1; of components.
for (;;) { dent set.
"DFSMatching.h" da4196, 20 lines
return {-v[0], ans}; // min cost Time: O (E + V ) 76b5c9, 24 lines
fill(all(A), 0); }
fill(all(B), 0); vi cover(vector<vi>& g, int n, int m) { vi val, comp, z, cont;
cur.clear(); vi match(m, -1); int Time, ncomps;
for (int a : btoa) if(a != -1) A[a] = -1; int res = dfsMatching(g, match); GeneralMatching.h template<class G, class F> int dfs(int j, G& g
rep(a,0,sz(g)) if(A[a] == 0) cur.push_back vector<bool> lfound(n, true), seen(m); Description: Matching for general graphs. Fails with , F& f) {
(a); for (int it : match) if (it != -1) lfound[it probability N/mod. int low = val[j] = ++Time, x; z.push_back(j)
Time: O N 3

for (int lay = 1;; lay++) { ] = false; ;
bool islast = 0; vi q, cover; "../numerical/MatrixInverse-mod.h" cb1912, 40 lines for (auto e : g[j]) if (comp[e] < 0)
next.clear(); rep(i,0,n) if (lfound[i]) q.push_back(i); vector<pii> generalMatching(int N, vector<pii low = min(low, val[e] ?: dfs(e,g,f));
for (int a : cur) for (int b : g[a]) { while (!q.empty()) { >& ed) {
if (btoa[b] == -1) { int i = q.back(); q.pop_back(); vector<vector<ll>> mat(N, vector<ll>(N)), A; if (low == val[j]) {
B[b] = lay; lfound[i] = 1; for (pii pa : ed) { do {
islast = 1; for (int e : g[i]) if (!seen[e] && match[e int a = pa.first, b = pa.second, r = rand x = z.back(); z.pop_back();
} ] != -1) { () % mod; comp[x] = ncomps;
else if (btoa[b] != a && !B[b]) { seen[e] = true; mat[a][b] = r, mat[b][a] = (mod - r) % mod cont.push_back(x);
B[b] = lay; q.push_back(match[e]); ; } while (x != j);
next.push_back(btoa[b]); } } f(cont); cont.clear();
} } ncomps++;
} rep(i,0,n) if (!lfound[i]) cover.push_back(i int r = matInv(A = mat), M = 2*N - r, fi, fj }
if (islast) break; ); ; return val[j] = low;
BRACU BiconnectedComponents 2sat EulerWalk EdgeColoring MaximalCliques MaximumClique 13
} Usage: TwoSat ts(number of boolean variables); }; adj[right][e] = -1;
template<class G, class F> void scc(G& g, F f) ts.either(0, ∼3); // Var 0 is true or var 3 is free[right] = e;
{ false EulerWalk.h }
int n = sz(g); ts.setValue(2); // Var 2 is true Description: Eulerian undirected/directed path/cycle adj[u][d] = fan[i];
val.assign(n, 0); comp.assign(n, -1); ts.atMostOne({0,∼1,2}); // <= 1 of vars 0, ∼1 algorithm. Input should be a vector of (dest, global edge adj[fan[i]][d] = u;
Time = ncomps = 0; and 2 are true index), where for undirected graphs, forward/backward for (int y : {fan[0], u, end})
rep(i,0,n) if (comp[i] < 0) dfs(i, g, f); ts.solve(); // Returns true iff it is solvable edges have the same index. Returns a list of nodes in for (int& z = free[y] = 0; adj[y][z] !=
} ts.values[0..N-1] holds the assigned values to the Eulerian path/cycle with src at both start and end, -1; z++);
the vars or empty list if no cycle/path exists. To get edge indices }
Time: O (N + E), where N is the number of boolean back, add .second to s and ret. rep(i,0,sz(eds))
variables, and E is the number of clauses. 5f9706, 56 lines Time: O (V + E) for (tie(u, v) = eds[i]; adj[u][ret[i]] !=
780b64, 15 lines
BiconnectedComponents.h struct TwoSat {
v;) ++ret[i];
vi eulerWalk(vector<vector<pii>>& gr, int return ret;
int N; nedges, int src=0) { }
Description: Finds all biconnected components in an vector<vi> gr; int n = sz(gr);
undirected graph, and runs a callback for the edges in vi values; // 0 = false , 1 = true vi D(n), its(n), eu(nedges), ret, s = {src};
each. In a biconnected component there are at least two D[src]++; // to allow Euler paths , not j u s t 7.6 Heuristics
distinct paths between any two nodes. Note that a node TwoSat(int n = 0) : N(n), gr(2*n) {} cycles
can be in several components. An edge which is not in a MaximalCliques.h
while (!s.empty()) { Description: Runs a callback for all maximal cliques in
component is a bridge, i.e., not part of any cycle. int addVar() { // ( optional ) int x = s.back(), y, e, &it = its[x], end
Usage: int eid = 0; ed.resize(N); gr.emplace_back(); a graph (given as a symmetric bitset matrix; self-edges
= sz(gr[x]); not allowed). Callback is given a bitset representing the
for each edge (a,b) { gr.emplace_back(); if (it == end){ ret.push_back(x); s.
ed[a].emplace back(b, eid); return N++; maximal clique.
pop_back(); continue; }  
ed[b].emplace back(a, eid++); } } tie(y, e) = gr[x][it++]; Time: O 3n/3 , much faster for sparse graphs
b0d5b1, 12 lines
bicomps([&](const vi& edgelist) {...}); if (!eu[e]) {
Time: O (E + V ) void either(int f, int j) { typedef bitset<128> B;
2965e5, 33 lines D[x]--, D[y]++; template<class F>
f = max(2*f, -1-2*f); eu[e] = 1; s.push_back(y);
vi num, st; j = max(2*j, -1-2*j); void cliques(vector<B>& eds, F f, B P = ∼B(),
vector<vector<pii>> ed; }} B X={}, B R={}) {
gr[f].push_back(j^1); for (int x : D) if (x < 0 || sz(ret) !=
int Time; gr[j].push_back(f^1); if (!P.any()) { if (!X.any()) f(R); return;
template<class F> nedges+1) return {}; }
} return {ret.rbegin(), ret.rend()};
int dfs(int at, int par, F& f) { void setValue(int x) { either(x, x); } auto q = (P | X)._Find_first();
int me = num[at] = ++Time, e, y, top = me; } auto cands = P & ∼eds[q];
for (auto pa : ed[at]) if (pa.second != par) void atMostOne(const vi& li) { // ( optional ) rep(i,0,sz(eds)) if (cands[i]) {
{ if (sz(li) <= 1) return; 7.5 Coloring R[i] = 1;
tie(y, e) = pa; int cur = ∼li[0]; cliques(eds, f, P & eds[i], X & eds[i], R)
if (num[y]) { EdgeColoring.h ;
rep(i,2,sz(li)) { Description: Given a simple, undirected graph with
top = min(top, num[y]); int next = addVar(); R[i] = P[i] = 0; X[i] = 1;
if (num[y] < me) max degree D, computes a (D + 1)-coloring of the edges }
either(cur, ∼li[i]); such that no neighboring edges share a color. (D-coloring
st.push_back(e); either(cur, next); }
} else { is NP-hard, but can be done for bipartite graphs by re-
either(∼li[i], next); peated matchings of max-degree nodes.)
int si = sz(st); cur = ∼next;
int up = dfs(y, e, f); Time: O (N M ) e210e2, 31 lines
MaximumClique.h
} Description: Quickly finds a maximum clique of a graph
top = min(top, up); either(cur, ∼li[1]); vi edgeColoring(int N, vector<pii> eds) {
if (up == me) { (given as symmetric bitset matrix; self-edges not al-
} vi cc(N + 1), ret(sz(eds)), fan(N), free(N), lowed). Can be used to find a maximum independent
st.push_back(e); loc;
f(vi(st.begin() + si, st.end())); set by finding a clique of the complement graph.
vi val, comp, z; int time = 0; for (pii e : eds) ++cc[e.first], ++cc[e. Time: Runs in about 1s for n=155 and worst case ran-
st.resize(si); int dfs(int i) { second];
} dom graphs (p=.90). Runs faster for sparsef7c0bc,
graphs.
49 lines
int low = val[i] = ++time, x; z.push_back( int u, v, ncols = *max_element(all(cc)) + 1;
else if (up < me) st.push_back(e); i); vector<vi> adj(N, vi(ncols, -1)); typedef vector<bitset<200>> vb;
else { /* e i s a bridge */ } for(int e : gr[i]) if (!comp[e]) for (pii e : eds) { struct Maxclique {
} low = min(low, val[e] ?: dfs(e)); tie(u, v) = e; double limit=0.025, pk=0;
} if (low == val[i]) do { fan[0] = v; struct Vertex { int i, d=0; };
return top; x = z.back(); z.pop_back(); loc.assign(ncols, 0); typedef vector<Vertex> vv;
} comp[x] = low; int at = u, end = u, d, c = free[u], ind = vb e;
if (values[x>>1] == -1) 0, i = 0; vv V;
template<class F> values[x>>1] = x&1; while (d = free[v], !loc[d] && (v = adj[u vector<vi> C;
void bicomps(F f) { } while (x != i); ][d]) != -1) vi qmax, q, S, old;
num.assign(sz(ed), 0); return val[i] = low; loc[d] = ++ind, cc[ind] = d, fan[ind] = void init(vv& r) {
rep(i,0,sz(ed)) if (!num[i]) dfs(i, -1, f); } v; for (auto& v : r) v.d = 0;
} cc[loc[d]] = c; for (auto& v : r) for (auto j : r) v.d +=
bool solve() { for (int cd = d; at != -1; cd ^= c ^ d, at e[v.i][j.i];
values.assign(N, -1); = adj[at][cd]) sort(all(r), [](auto a, auto b) { return a
val.assign(2*N, 0); comp = val; swap(adj[at][cd], adj[end = at][cd ^ c ^ .d > b.d; });
2sat.h rep(i,0,2*N) if (!comp[i]) dfs(i); d]); int mxD = r[0].d;
Description: Calculates a valid assignment to boolean rep(i,0,N) if (comp[2*i] == comp[2*i+1]) while (adj[fan[i]][d] != -1) { rep(i,0,sz(r)) r[i].d = min(i, mxD) + 1;
variables a, b, c,... to a 2-SAT problem, so that an ex- return 0; int left = fan[i], right = fan[++i], e = }
pression of the type (a∥∥b)&&(!a∥∥c)&&(d∥∥!b)&&... be- return 1; cc[i]; void expand(vv& R, int lev = 1) {
comes true, or reports that it is unsatisfiable. Negated } adj[u][e] = left; S[lev] += S[lev - 1] - old[lev];
variables are represented by bit-inversions (∼x). adj[left][e] = u; old[lev] = S[lev - 1];
BRACU MaximumIndependentSet BinaryLifting LCA CompressTree HLD LinkCutTree 14
while (sz(R)) { a = jmp(tbl, a, depth[a] - depth[b]); return ret; }
if (sz(q) + R.back().d <= sz(qmax)) if (a == b) return a; } };
return; for (int i = sz(tbl); i--;) {
q.push_back(R.back().i); int c = tbl[i][a], d = tbl[i][b]; HLD.h
vv T; if (c != d) a = c, b = d; Description: Decomposes a tree into vertex disjoint LinkCutTree.h
for(auto v:R) if (e[R.back().i][v.i]) T. } heavy paths and light edges such that the path from Description: Represents a forest of unrooted trees. You
push_back({v.i}); return tbl[0][a]; any leaf to the root contains at most log(n) light edges. can add and remove edges (as long as the result is still
if (sz(T)) { } Code does additive modifications and max queries, but a forest), and check whether two nodes are in the same
if (S[lev]++ / ++pk < limit) init(T); can support commutative segtree modifications/queries tree.
int j = 0, mxk = 1, mnk = max(sz(qmax) Time: All operations take amortized O (log N ).
- sz(q) + 1, 1);
LCA.h on paths and subtrees. Takes as input the full adjacency 5909e2, 90 lines
Description: Data structure for computing lowest com- list. VALS EDGES being true means that values are struct Node { // Splay tree . Root ’ s pp
C[1].clear(), C[2].clear(); stored in the edges, as opposed to the nodes. All val-
mon ancestors in a tree (with 0 as root). C should be an contains tree ’ s parent .
for (auto v : T) { ues initialized to the
int k = 1;
adjacency list of the tree, either directed or undirected.  segtree default. Root must be 0. Node *p = 0, *pp = 0, *c[2];
Time: O (N log N + Q) Time: O (log N )2 bool flip = 0;
auto f = [&](int i) { return e[v.i][ "../data-structures/LazySegmentTree.h" 6f34db, 46 lines
i]; };
"../data-structures/RMQ.h" 0f62fb, 21 lines Node() { c[0] = c[1] = 0; fix(); }
while (any_of(all(C[k]), f)) k++; struct LCA { template <bool VALS_EDGES> struct HLD { void fix() {
if (k > mxk) mxk = k, C[mxk + 1]. int T = 0; int N, tim = 0; if (c[0]) c[0]->p = this;
clear(); vi time, path, ret; vector<vi> adj; if (c[1]) c[1]->p = this;
if (k < mnk) T[j++].i = v.i; RMQ<int> rmq; vi par, siz, depth, rt, pos; // (+ update sum of subtree elements etc .
C[k].push_back(v.i); Node *tree; i f wanted)
} LCA(vector<vi>& C) : time(sz(C)), rmq((dfs(C HLD(vector<vi> adj_) }
if (j > 0) T[j - 1].d = 0; ,0,-1), ret)) {} : N(sz(adj_)), adj(adj_), par(N, -1), siz( void pushFlip() {
rep(k,mnk,mxk + 1) for (int i : C[k]) void dfs(vector<vi>& C, int v, int par) { N, 1), depth(N), if (!flip) return;
T[j].i = i, T[j++].d = k; time[v] = T++; rt(N),pos(N),tree(new Node(0, N)){ dfsSz flip = 0; swap(c[0], c[1]);
expand(T, lev + 1); for (int y : C[v]) if (y != par) { (0); dfsHld(0); } if (c[0]) c[0]->flip ^= 1;
} else if (sz(q) > sz(qmax)) qmax = q; path.push_back(v), ret.push_back(time[v void dfsSz(int v) { if (c[1]) c[1]->flip ^= 1;
q.pop_back(), R.pop_back(); ]); if (par[v] != -1) adj[v].erase(find(all( }
} dfs(C, y, v); adj[v]), par[v])); int up() { return p ? p->c[1] == this : -1;
} } for (int& u : adj[v]) { }
vi maxClique() { init(V), expand(V); return } par[u] = v, depth[u] = depth[v] + 1; void rot(int i, int b) {
qmax; } dfsSz(u); int h = i ^ b;
Maxclique(vb conn) : e(conn), C(sz(e)+1), S( int lca(int a, int b) { siz[v] += siz[u]; Node *x = c[i], *y = b == 2 ? x : x->c[h],
sz(C)), old(S) { if (a == b) return a; if (siz[u] > siz[adj[v][0]]) swap(u, adj *z = b ? y : x;
rep(i,0,sz(e)) V.push_back({i}); tie(a, b) = minmax(time[a], time[b]); [v][0]); if ((y->p = p)) p->c[up()] = y;
} return path[rmq.query(a, b)]; } c[i] = z->c[i ^ 1];
}; } } if (b < 2) {
// d i s t (a , b){return depth [ a ] + depth [ b ] = 2* void dfsHld(int v) { x->c[h] = y->c[h ^ 1];
depth [ lca (a , b) ] ;} pos[v] = tim++; z->c[h ^ 1] = b ? x : this;
MaximumIndependentSet.h }; for (int u : adj[v]) { }
Description: To obtain a maximum independent set of rt[u] = (u == adj[v][0] ? rt[v] : u); y->c[i ^ 1] = b ? this : x;
a graph, find a max clique of the complement. If the dfsHld(u); fix(); x->fix(); y->fix();
graph is bipartite, see MinimumVertexCover. CompressTree.h } if (p) p->fix();
Description: Given a rooted tree and a subset S of } swap(pp, y->pp);
nodes, compute the minimal subtree that contains all the template <class B> void process(int u, int v }
7.7 Trees nodes by adding all (at most |S| − 1) pairwise LCA’s and , B op) { void splay() {
compressing edges. Returns a list of (par, orig index) for (; rt[u] != rt[v]; v = par[rt[v]]) { for (pushFlip(); p; ) {
BinaryLifting.h representing a tree rooted at 0. The root points to itself. if (depth[rt[u]] > depth[rt[v]]) swap(u, if (p->p) p->p->pushFlip();
Description: Calculate power of two jumps in a tree, to Time: O (|S| log |S|)
support fast upward jumps and LCAs. Assumes the root v); p->pushFlip(); pushFlip();
"LCA.h" 9775a0, 21 lines op(pos[rt[v]], pos[v] + 1); int c1 = up(), c2 = p->up();
node points to itself.
Time: construction O (N log N ), queries Obfce85,
(log N25
) lines typedef vector<pair<int, int>> vpi; } if (c2 == -1) p->rot(c1, 2);
vpi compressTree(LCA& lca, const vi& subset) { if (depth[u] > depth[v]) swap(u, v); else p->p->rot(c2, c1 != c2);
vector<vi> treeJump(vi& P){ static vi rev; rev.resize(sz(lca.time)); op(pos[u] + VALS_EDGES, pos[v] + 1); }
int on = 1, d = 1; vi li = subset, &T = lca.time; } }
while(on < sz(P)) on *= 2, d++; auto cmp = [&](int a, int b) { return T[a] < void modifyPath(int u, int v, int val) { Node* first() {
vector<vi> jmp(d, P); T[b]; }; process(u, v, [&](int l, int r) { tree-> pushFlip();
rep(i,1,d) rep(j,0,sz(P)) sort(all(li), cmp); add(l, r, val); }); return c[0] ? c[0]->first() : (splay(),
jmp[i][j] = jmp[i-1][jmp[i-1][j]]; int m = sz(li)-1; } this);
return jmp; rep(i,0,m) { int queryPath(int u, int v) { // Modify }
} int a = li[i], b = li[i+1]; depending on problem };
li.push_back(lca.lca(a, b)); int res = -1e9;
int jmp(vector<vi>& tbl, int nod, int steps){ } process(u, v, [&](int l, int r) { struct LinkCut {
rep(i,0,sz(tbl)) sort(all(li), cmp); res = max(res, tree->query(l, r)); vector<Node> node;
if(steps&(1<<i)) nod = tbl[i][nod]; li.erase(unique(all(li)), li.end()); }); LinkCut(int N) : node(N) {}
return nod; rep(i,0,sz(li)) rev[li[i]] = i; return res;
} vpi ret = {pii(0, li[0])}; } void link(int u, int v) { // add an edge (u,
rep(i,0,sz(li)-1) { int querySubtree(int v) { // modifySubtree v)
int lca(vector<vi>& tbl, vi& depth, int a, int int a = li[i], b = li[i+1]; i s similar assert(!connected(u, v));
b) { ret.emplace_back(rev[lca.lca(a, b)], b); return tree->query(pos[v] + VALS_EDGES, makeRoot(&node[u]);
if (depth[a] < depth[b]) swap(a, b); } pos[v] + siz[v]); node[u].pp = &node[v];
BRACU DirectedMST Point lineDistance SegmentDistance SegmentIntersection 15
} pair<ll, vi> dmst(int n, int r, vector<Edge>& 7.8.2 Erdős–Gallai theorem Description:
void cut(int u, int v) { // remove an edge ( g) { Returns the signed distance between point p and the line con-
u, v) RollbackUF uf(n);
A simple graph with node degrees d1 ≥ · · · ≥ dn taining points a and b. Positive value on left side and negative
Node *x = &node[u], *top = &node[v]; vector<Node*> heap(n); exists iff d1 + · · · + dn is even and for every on right as seen from a towards b. a==b gives nan. P is sup-
makeRoot(top); x->splay(); for (Edge e : g) heap[e.b] = merge(heap[e.b k = 1 . . . n, posed to be Point<T> or Point3D<T> where T is e.g. double
assert(top == (x->pp ?: x->c[0])); ], new Node{e}); or long long. It uses products in intermediate steps so watch
if (x->pp) x->pp = 0; ll res = 0; out for overflow if using int or long long. Using Point3D wil
else { vi seen(n, -1), path(n), par(n); k n always give a non-negative distance. For Point3D, call .dist
on the result of the cross product.
X X
x->c[0] = top->p = 0; seen[r] = r;
di ≤ k(k − 1) + min(di , k).
x->fix(); vector<Edge> Q(n), in(n, {-1,-1}), comp; res
i=1 i=k+1
} deque<tuple<int, int, vector<Edge>>> cycs; e p
} rep(s,0,n) {
bool connected(int u, int v) { // are u, v int u = s, qi = 0, w;
in the same tree? while (seen[u] < 0) { s
Node* nu = access(&node[u])->first(); if (!heap[u]) return {-1,{}}; "Point.h" f6bf6b, 4 lines

}
return nu == access(&node[v])->first(); Edge e = heap[u]->top();
heap[u]->delta -= e.w, pop(heap[u]);
Geometry (8) template<class P>
double lineDist(const P& a, const P& b, const
void makeRoot(Node* u) { Q[qi] = e, path[qi++] = u, seen[u] = s; P& p) {
access(u);
u->splay();
res += e.w, u = uf.find(e.a);
if (seen[u] == s) {
8.1 Geometric primitives return (double)(b-a).cross(p-a)/(b-a).dist()
;
if(u->c[0]) { Node* cyc = 0; Point.h }
u->c[0]->p = 0; int end = qi, time = uf.time(); Description: Class to handle points in the plane. T can
u->c[0]->flip ^= 1; do cyc = merge(cyc, heap[w = path[--qi be e.g. double or long long. (Avoid int.) 47ec0a, 28 lines
u->c[0]->pp = u; ]]);
template <class T> int sgn(T x) { return (x > SegmentDistance.h
u->c[0] = 0; while (uf.join(u, w));
e resthe
0) - (x < 0); } Description:
u->fix(); u = uf.find(u), heap[u] = cyc, seen[u]
template<class T> Returns p shortest distance between point p and the line
} = -1; segment from point s to e.
struct Point {
} cycs.push_front({u, time, {&Q[qi], &Q[
typedef Point P;
Node* access(Node* u) { end]}});
T x, y;
s
u->splay(); } Usage: Point<double> a, b(2,2), p(1,1);
explicit Point(T x=0, T y=0) : x(x), y(y) {}
while (Node* pp = u->pp) { } bool onSegment = segDist(a,b,p) < 1e-10;
bool operator<(P p) const { return tie(x,y)
pp->splay(); u->pp = 0; rep(i,0,qi) in[uf.find(Q[i].b)] = Q[i]; "Point.h" 5c88f4, 6 lines
< tie(p.x,p.y); }
if (pp->c[1]) { } typedef Point<double> P;
bool operator==(P p) const { return tie(x,y)
pp->c[1]->p = 0; pp->c[1]->pp = pp; } double segDist(P& s, P& e, P& p) {
==tie(p.x,p.y); }
pp->c[1] = u; pp->fix(); u = pp; for (auto& [u,t,comp] : cycs) { // restore if (s==e) return (p-s).dist();
P operator+(P p) const { return P(x+p.x, y+p
} s o l ( optional ) auto d = (e-s).dist2(), t = min(d,max(.0,(p-
.y); }
return u; uf.rollback(t); s).dot(e-s)));
P operator-(P p) const { return P(x-p.x, y-p
} Edge inEdge = in[u]; return ((p-s)*d-(e-s)*t).dist()/d;
.y); }
}; for (auto& e : comp) in[uf.find(e.b)] = e; }
P operator*(T d) const { return P(x*d, y*d);
in[uf.find(inEdge.b)] = inEdge;
}
DirectedMST.h }
P operator/(T d) const { return P(x/d, y/d);
Description: Finds a minimum spanning tree/arbores- rep(i,0,n) par[i] = in[i].a;
} SegmentIntersection.h
cence of a directed graph, given a root node. If no MST return {res, par}; Description:
T dot(P p) const { return x*p.x + y*p.y; }
exists, returns -1. } If a unique intersection point between the line segments going
T cross(P p) const { return x*p.y - y*p.x; }
Time: O (E log V ) from s1 to e1 and from s2 to e2 exists then it is returned
T cross(P a, P b) const { return (a-*this).
39e620, 60 lines
If no intersection point exists an empty vector is returned
"../data-structures/UnionFindRollback.h" cross(b-*this); }
If infinitely many exist a vector with 2 elements is returned
struct Edge { int a, b; ll w; }; T dist2() const { return x*x + y*y; }
containing the endpoints of the common line segment. The
struct Node { double dist() const { return sqrt((double)
wrong position will be returned if P is Point<ll> and the in-
Edge key; dist2()); }
tersection point does not have integer coordinates. Products
Node *l, *r; // angle to x=axis in interval [= pi , pi ]
of three coordinates are used in intermediate steps so watch
ll delta; double angle() const { return atan2(y, x); }
out for overflow if using int or long long.
void prop() { P unit() const { return *this/dist(); } //
key.w += delta; makes d i s t ()=1 e1
if (l) l->delta += delta; P perp() const { return P(-y, x); } // e2
if (r) r->delta += delta; 7.8 Math rotates +90 degrees r1
delta = 0;
7.8.1 Number of Spanning P normal() const { return perp().unit(); } s1 s2
} // returns point rotated ’a ’ radians ccw
Edge top() { prop(); return key; } Trees around the origin Usage: vector<P> inter =
}; P rotate(double a) const { segInter(s1,e1,s2,e2);
Create an N × N matrix mat, and for each edge return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos( if (sz(inter)==1)
Node *merge(Node *a, Node *b) {
if (!a || !b) return a ?: b; a → b ∈ G, do mat[a][b]--, mat[b][b]++ a)); } cout << "segments intersect at " << inter[0]
a->prop(), b->prop(); (and mat[b][a]--, mat[a][a]++ if G is friend ostream& operator<<(ostream& os, P p) << endl;
if (a->key.w > b->key.w) swap(a, b); { "Point.h", "OnSegment.h" 9d57f2, 13 lines
swap(a->l, (a->r = merge(b, a->r)));
undirected). Remove the ith row and column return os << "(" << p.x << "," << p.y << " template<class P> vector<P> segInter(P a, P b,
return a; and take the determinant; this yields the )"; } P c, P d) {
} number of directed spanning trees rooted at i (if }; auto oa = c.cross(d, a), ob = c.cross(d, b),
void pop(Node*& a) { a->prop(); a = merge(a->l oc = a.cross(b, c), od = a.cross(b, d);
, a->r); } G is undirected, remove any // Checks i f intersection i s single non=
row/column). lineDistance.h endpoint point .
BRACU lineIntersection sideOf OnSegment linearTransformation Angle CircleIntersection CircleTangents CirclePolygonIntersection circumcircle 16
if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn( OnSegment.h // Given two points , t h i s calculates the P v = (d * dr + d.perp() * sqrt(h2) * sign
od) < 0) Description: Returns true iff p lies on the line segment smallest angle between ) / d2;
return {(a * ob - b * oa) / (ob - oa)}; from s to e. Use (segDist(s,e,p)<=epsilon) instead // them, i . e . , the angle that covers the out.push_back({c1 + v * r1, c2 + v * r2});
set<P> s; when using Point<double>. defined l i n e segment . }
if (onSegment(c, d, a)) s.insert(a); "Point.h" c597e8, 3 lines pair<Angle, Angle> segmentAngles(Angle a, if (h2 == 0) out.pop_back();
if (onSegment(c, d, b)) s.insert(b); template<class P> bool onSegment(P s, P e, P p Angle b) { return out;
if (onSegment(a, b, c)) s.insert(c); ) { if (b < a) swap(a, b); }
if (onSegment(a, b, d)) s.insert(d); return p.cross(s, e) == 0 && (s - p).dot(e - return (b < a.t180() ?
return {all(s)}; p) <= 0; make_pair(a, b) : make_pair(b, a.
} } t360()));
} CirclePolygonIntersection.h
Angle operator+(Angle a, Angle b) { // point a
lineIntersection.h linearTransformation.h + vector b Description: Returns the area of the intersection of a
Angle r(a.x + b.x, a.y + b.y, a.t);
Description: r p1
Description: circle with a ccw polygon.
If a unique intersection point of the lines going through s1,e1Apply the linear transformation (translation, rotation and if (a.t180() < r) r.t--; Time: O (n)
and s2,e2 exists {1, point} is returned. If no intersection point
scaling) which takes line p0-p1 to line q0-q1 to point r. return r.t180() < a ? r.t360() : r;
exists {0, (0,0)} is returned and if infinitely many exists {-1,p0 res }
"../../content/geometry/Point.h" a1ee63, 19 lines

(0,0)} is returned. The wrong position will be returned if P q0 Angle angleDiff(Angle a, Angle b) { // angle b typedef Point<double> P;
is Point<ll> and the intersection point does not have integer q1 = angle a #define arg(p, q) atan2(p.cross(q), p.dot(q))
coordinates. Products of three coordinates are used in inter- "Point.h" 03a306, 6 lines int tu = b.t - a.t; a.t = b.t; double circlePoly(P c, double r, vector<P> ps)
mediate steps so watch out for overflow if using int or ll. typedef Point<double> P; return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x {
, tu - (b < a)}; auto tri = [&](P p, P q) {
P linearTransformation(const P& p0, const P&
auto r2 = r * r / 2;
e2 r p1, }
P d = q - p;
const P& q0, const P& q1, const P& r) {
e1 s2 P dp = p1-p0, dq = q1-q0, num(dp.cross(dq),
auto a = d.dot(p)/d.dist2(), b = (p.dist2
s1 dp.dot(dq)); 8.2 Circles ()-r*r)/d.dist2();
auto det = a * a - b;
Usage: auto res = lineInter(s1,e1,s2,e2); return q0 + P((r-p0).cross(num), (r-p0).dot( CircleIntersection.h if (det <= 0) return arg(p, q) * r2;
if (res.first == 1) num))/dp.dist2(); Description: Computes the pair of points at which two auto s = max(0., -a-sqrt(det)), t = min
cout << "intersection point at " << } circles intersect. Returns false in case of no intersection. (1., -a+sqrt(det));
res.second << endl; "Point.h" 84d6d3, 11 lines if (t < 0 || 1 <= s) return arg(p, q) * r2
"Point.h" a01f81, 8 lines ;
Angle.h typedef Point<double> P;
template<class P> Description: A class for ordering angles (as represented bool circleInter(P a,P b,double r1,double r2, P u = p + d * s, v = p + d * t;
pair<int, P> lineInter(P s1, P e1, P s2, P e2) by int points and a number of rotations around the ori- pair<P, P>* out) { return arg(p,u) * r2 + u.cross(v)/2 + arg(
{ gin). Useful for rotational sweeping. Sometimes also rep- if (a == b) { assert(r1 != r2); return false v,q) * r2;
auto d = (e1 - s1).cross(e2 - s2); resents points or vectors. ; } };
if (d == 0) // i f p a r a l l e l Usage: vector<Angle> v = {w[0], w[0].t360() P vec = b - a; auto sum = 0.0;
return {-(s1.cross(e1, s2) == 0), P(0, 0)} ...}; // sorted double d2 = vec.dist2(), sum = r1+r2, dif = rep(i,0,sz(ps))
; int j = 0; rep(i,0,n) { while (v[j] < r1-r2, sum += tri(ps[i] - c, ps[(i + 1) % sz(ps)]
auto p = s2.cross(e1, e2), q = s2.cross(e2, v[i].t180()) ++j; } p = (d2 + r1*r1 - r2*r2)/(d2*2), h2 = - c);
s1); // sweeps j such that (j-i) represents the r1*r1 - p*p*d2; return sum;
return {1, (s1 * p + e1 * q) / d}; number of positively oriented triangles with if (sum*sum < d2 || dif*dif > d2) return }
} vertices at 0 and i false;
0f0602, 35 lines
P mid = a + vec*p, per = vec.perp() * sqrt(
struct Angle { fmax(0, h2) / d2);
sideOf.h int x, y; *out = {mid + per, mid - per}; circumcircle.h
Description: Returns where p is as seen from s towards int t; return true; Description:
e. 1/0/-1 ⇔ left/on line/right. If the optional argument Angle(int x, int y, int t=0) : x(x), y(y), t } The circumcirle of a triangle is the circle intersecting al
eps is given 0 is returned if p is within distance eps from (t) {} three vertices. ccRadius returns the radius of the circle going
the line. P is supposed to be Point<T> where T is e.g. Angle operator-(Angle b) const { return {x-b through points A, B and C and ccCenter returns the center
double or long long. It uses products in intermediate .x, y-b.y, t}; } CircleTangents.h of the same circle.
steps so watch out for overflow if using int or long long. int half() const { Description: Finds the external tangents of two circles, B
Usage: bool left = sideOf(p1,p2,q)==1; assert(x || y); or internal if r2 is negated. Can return 0, 1, or 2 tan- r c
"Point.h" 3af81c, 9 lines return y < 0 || (y == 0 && x < 0); gents – 0 if one circle contains the other (or overlaps it, C
template<class P> } in the internal case, or if the circles are the same); 1 if A
Angle t90() const { return {-y, x, t + (half the circles are tangent to each other (in which case .first
int sideOf(P s, P e, P p) { return sgn(s.cross "Point.h" 1caa3a, 9 lines
() && x >= 0)}; } = .second and the tangent line is perpendicular to the
(e, p)); } line between the centers). .first and .second give the tan- typedef Point<double> P;
Angle t180() const { return {-x, -y, t +
gency points at circle 1 and 2 respectively. To find the double ccRadius(const P& A, const P& B, const
template<class P> half()}; }
tangents of a circle with a point set r2 to 0. P& C) {
int sideOf(const P& s, const P& e, const P& p, Angle t360() const { return {x, y, t + 1}; }
"Point.h" b0153d, 13 lines return (B-A).dist()*(C-B).dist()*(A-C).dist
double eps) { };
()/
auto a = (e-s).cross(p-s); bool operator<(Angle a, Angle b) { template<class P>
abs((B-A).cross(C-A))/2;
double l = (e-s).dist()*eps; // add a . dist2 () and b . dist2 () to also vector<pair<P, P>> tangents(P c1, double r1, P
}
return (a > l) - (a < -l); compare distances c2, double r2) {
P ccCenter(const P& A, const P& B, const P& C)
} return make_tuple(a.t, a.half(), a.y * (ll)b P d = c2 - c1;
{
.x) < double dr = r1 - r2, d2 = d.dist2(), h2 = d2
P b = C-A, c = B-A;
make_tuple(b.t, b.half(), a.x * (ll)b - dr * dr;
return A + (b*c.dist2()-c*b.dist2()).perp()/
.y); if (d2 == 0 || h2 < 0) return {};
b.cross(c)/2;
} vector<pair<P, P>> out;
}
for (double sign : {-1, 1}) {
BRACU MinimumEnclosingCircle InsidePolygon PolygonArea PolygonCenter PolygonCut ConvexHull HullDiameter PointInsideHull LineHullIntersection ClosestPair 17
MinimumEnclosingCircle.h PolygonCenter.h HullDiameter.h if (extr(0)) return 0;
Description: Returns the center of mass for a polygon. Description: Returns the two points with max distance while (lo + 1 < hi) {
Description: Computes the minimum circle that en- Time: O (n) on a convex hull (ccw, no duplicate/collinear points). int m = (lo + hi) / 2;
closes a set of points. "Point.h" 9706dc, 9 lines Time: O (n) if (extr(m)) return m;
Time: expected O (n) typedef Point<double> P; "Point.h" c571b8, 12 lines int ls = cmp(lo + 1, lo), ms = cmp(m + 1,
"circumcircle.h" 09dd0a, 17 lines P polygonCenter(const vector<P>& v) { typedef Point<ll> P; m);
P res(0, 0); double A = 0; array<P, 2> hullDiameter(vector<P> S) { (ls < ms || (ls == ms && ls == cmp(lo, m))
pair<P, double> mec(vector<P> ps) { ? hi : lo) = m;
shuffle(all(ps), mt19937(time(0))); for (int i = 0, j = sz(v) - 1; i < sz(v); j int n = sz(S), j = n < 2 ? 0 : 1;
= i++) { pair<ll, array<P, 2>> res({0, {S[0], S[0]}}) }
P o = ps[0]; return lo;
double r = 0, EPS = 1 + 1e-8; res = res + (v[i] + v[j]) * v[j].cross(v[i ;
]); rep(i,0,j) }
rep(i,0,sz(ps)) if ((o - ps[i]).dist() > r *
EPS) { A += v[j].cross(v[i]); for (;; j = (j + 1) % n) {
} res = max(res, {(S[i] - S[j]).dist2(), { #define cmpL(i) sgn(a.cross(poly[i], b))
o = ps[i], r = 0; template <class P>
rep(j,0,i) if ((o - ps[j]).dist() > r * return res / A / 3; S[i], S[j]}});
} if ((S[(j + 1) % n] - S[j]).cross(S[i + array<int, 2> lineHull(P a, P b, vector<P>&
EPS) { poly) {
o = (ps[i] + ps[j]) / 2; 1] - S[i]) >= 0)
break; int endA = extrVertex(poly, (a - b).perp());
r = (o - ps[i]).dist(); PolygonCut.h } int endB = extrVertex(poly, (b - a).perp());
rep(k,0,j) if ((o - ps[k]).dist() > r * Description: if (cmpL(endA) < 0 || cmpL(endB) > 0)
Returns ea vector with the vertices of a polygon with every-
EPS) { return res.second;
} return {-1, -1};
o = ccCenter(ps[i], ps[j], ps[k]); thing to the left of the line going from s to e cut away. array<int, 2> res;
r = (o - ps[i]).dist(); rep(i,0,2) {
} PointInsideHull.h int lo = endB, hi = endA, n = sz(poly);
} s
Usage: vector<P> p = ...; Description: Determine whether a point t lies inside a while ((lo + 1) % n != hi) {
} p = polygonCut(p, P(0,0), P(1,0)); convex hull (CCW order, with no collinear points). Re- int m = ((lo + hi + (lo < hi ? 0 : n)) /
return {o, r}; "Point.h", "lineIntersection.h" f2b7d4, 13 lines turns true if point lies within the hull. If strict is true, 2) % n;
} points on the boundary aren’t included. (cmpL(m) == cmpL(endB) ? lo : hi) = m;
typedef Point<double> P;
Time: O (log N ) }
vector<P> polygonCut(const vector<P>& poly, P
"Point.h", "sideOf.h", "OnSegment.h" 71446b, 14 lines
s, P e) { res[i] = (lo + !cmpL(hi)) % n;
vector<P> res; typedef Point<ll> P; swap(endA, endB);
8.3 Polygons rep(i,0,sz(poly)) {
P cur = poly[i], prev = i ? poly[i-1] : bool inHull(const vector<P>& l, P p, bool
}
if (res[0] == res[1]) return {res[0], -1};
InsidePolygon.h poly.back(); strict = true) { if (!cmpL(res[0]) && !cmpL(res[1]))
Description: Returns true if p lies within the polygon. bool side = s.cross(e, cur) < 0; int a = 1, b = sz(l) - 1, r = !strict; switch ((res[0] - res[1] + sz(poly) + 1) %
If strict is true, it returns false for points on the bound- if (side != (s.cross(e, prev) < 0)) if (sz(l) < 3) return r && onSegment(l[0], l sz(poly)) {
ary. The algorithm uses products in intermediate steps res.push_back(lineInter(s, e, cur, prev) .back(), p); case 0: return {res[0], res[0]};
so watch out for overflow. .second); if (sideOf(l[0], l[a], l[b]) > 0) swap(a, b) case 2: return {res[1], res[1]};
Usage: vector<P> v = {P{4,4}, P{1,2}, P{2,1}}; if (side) ; }
bool in = inPolygon(v, P{3, 3}, false); res.push_back(cur); if (sideOf(l[0], l[a], p) >= r || sideOf(l return res;
Time: O (n) } [0], l[b], p)<= -r) }
"Point.h", "OnSegment.h", "SegmentDistance.h" 2bf504, 11 lines return res; return false;
template<class P> } while (abs(a - b) > 1) {
bool inPolygon(vector<P> &p, P a, bool strict int c = (a + b) / 2; 8.4 Misc. Point Set
= true) { (sideOf(l[0], l[c], p) > 0 ? b : a) = c;
int cnt = 0, n = sz(p);
ConvexHull.h } Problems
Description: return sgn(l[a].cross(l[b], p)) < r;
rep(i,0,n) {
Returns a vector of the points of the convex hull in counter-
}
ClosestPair.h
P q = p[(i + 1) % n]; Description: Finds the closest pair of points.
clockwise order. Points on the edge of the hull between two
if (onSegment(p[i], q, a)) return !strict; Time: O (n log n)
other points are not considered part of the hull.
//or : i f ( segDist (p [ i ] , q , a) <= eps) LineHullIntersection.h "Point.h" ac41a6, 17 lines
return ! s t r i c t ; Description: Line-convex polygon intersection. The typedef Point<ll> P;
cnt ^= ((a.y<p[i].y) - (a.y<q.y)) * a. polygon must be ccw and have no collinear points. line- pair<P, P> closest(vector<P> v) {
cross(p[i], q) > 0; Time: O (n log n)
Hull(line, poly) returns a pair describing the intersection assert(sz(v) > 1);
310954, 13 lines
of a line with the polygon: ˆ (−1, −1) if no collision,
"Point.h"
} set<P> S;
return cnt; typedef Point<ll> P; ˆ (i, −1) if touching the corner i, ˆ (i, i) if along side sort(all(v), [](P a, P b) { return a.y < b.y
} vector<P> convexHull(vector<P> pts) { (i, i + 1), ˆ (i, j) if crossing sides (i, i + 1) and (j, j + 1). ; });
if (sz(pts) <= 1) return pts; In the last case, if a corner i is crossed, this is treated as pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P
sort(all(pts)); happening on side (i, i + 1). The points are returned in ()}};
vector<P> h(sz(pts)+1); the same order as the line hits the polygon. extrVertex
PolygonArea.h int s = 0, t = 0; returns the point of a hull with the max projection onto
int j = 0;
Description: Returns twice the signed area of a poly- for (P p : v) {
for (int it = 2; it--; s = --t, reverse(all( a line.
gon. Clockwise enumeration gives negative area. Watch P d{1 + (ll)sqrt(ret.first), 0};
pts))) Time: O (log n)
out for overflow if using int as T! while (v[j].y <= p.y - d.x) S.erase(v[j
for (P p : pts) { "Point.h" 7cf45b, 39 lines
"Point.h" f12300, 6 lines ++]);
while (t >= s + 2 && h[t-2].cross(h[t
#define cmp(i,j) sgn(dir.perp().cross(poly[(i) auto lo = S.lower_bound(p - d), hi = S.
template<class T> -1], p) <= 0) t--;
%n]-poly[(j)%n])) upper_bound(p + d);
T polygonArea2(vector<Point<T>>& v) { h[t++] = p;
#define extr(i) cmp(i + 1, i) >= 0 && cmp(i, i for (; lo != hi; ++lo)
T a = v.back().cross(v[0]); }
- 1 + n) < 0 ret = min(ret, {(*lo - p).dist2(), {*lo,
rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]); return {h.begin(), h.begin() + t - (t == 2
template <class P> int extrVertex(vector<P>& p}});
return a; && h[0] == h[1])};
poly, P dir) { S.insert(p);
} }
int n = sz(poly), lo = 0, hi = n; }
BRACU kdTree FastDelaunay PolyhedronVolume Point3D 18
return ret.second; T bfirst = f->distance(p), bsec = s-> splice(q, a->next()); return pts;
} distance(p); splice(q->r(), b); }
if (bfirst > bsec) swap(bsec, bfirst), return q;
kdTree.h swap(f, s); } 8.5 3D
Description: KD-tree (2d, can be extended to 3d)
"Point.h" bac5b0, 63 lines
// search c l o s e s t side f i r s t , other side pair<Q,Q> rec(const vector<P>& s) { PolyhedronVolume.h
i f needed if (sz(s) <= 3) { Description: Magic formula for the volume of a poly-
typedef long long T; auto best = search(f, p); Q a = makeEdge(s[0], s[1]), b = makeEdge(s hedron. Faces should point outwards.
typedef Point<T> P; 3058c3, 6 lines
if (bsec < best.first) [1], s.back());
const T INF = numeric_limits<T>::max(); best = min(best, search(s, p)); if (sz(s) == 2) return { a, a->r() }; template<class V, class L>
return best; splice(a->r(), b); double signedPolyVolume(const V& p, const L&
bool on_x(const P& a, const P& b) { return a.x } auto side = s[0].cross(s[1], s[2]); trilist) {
< b.x; } Q c = side ? connect(b, a) : 0; double v = 0;
bool on_y(const P& a, const P& b) { return a.y // find nearest point to a point , and i t s return {side < 0 ? c->r() : a, side < 0 ? for (auto i : trilist) v += p[i.a].cross(p[i
< b.y; } squared distance c : b->r() }; .b]).dot(p[i.c]);
// ( requires an arbitrary operator< for } return v / 6;
struct Node { Point) }
P pt; // i f t h i s i s a leaf , the single point pair<T, P> nearest(const P& p) { #define H(e) e->F(), e->p
in i t return search(root, p); #define valid(e) (e->F().cross(H(base)) > 0) Point3D.h
T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; } Q A, B, ra, rb; Description: Class to handle points in 3D space. T can
// bounds }; int half = sz(s) / 2; be e.g. double or long long.
Node *first = 0, *second = 0; 8058ae, 32 lines
tie(ra, A) = rec({all(s) - half});
tie(B, rb) = rec({sz(s) - half + all(s)}); template<class T> struct Point3D {
T distance(const P& p) { // min squared FastDelaunay.h typedef Point3D P;
Description: Fast Delaunay triangulation. Each cir- while ((B->p.cross(H(A)) < 0 && (A = A->next
distance to a point ())) || typedef const P& R;
T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x cumcircle contains none of the input points. There must T x, y, z;
be no duplicate points. If all points are on a line, no tri- (A->p.cross(H(B)) > 0 && (B = B->r()
); ->o))); explicit Point3D(T x=0, T y=0, T z=0) : x(x)
T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y angles will be returned. Should work for doubles as well, , y(y), z(z) {}
though there may be precision issues in ’circ’. Returns Q base = connect(B->r(), A);
); if (A->p == ra->p) ra = base->r(); bool operator<(R p) const {
return (P(x,y) - p).dist2(); triangles in order {t[0][0], t[0][1], t[0][2], t[1][0], . . . }, all return tie(x, y, z) < tie(p.x, p.y, p.z);
counter-clockwise. if (B->p == rb->p) rb = base;
} }
Time: O (n log n) bool operator==(R p) const {
"Point.h" eefdf5, 88 lines
#define DEL(e, init, dir) Q e = init->dir; if
Node(vector<P>&& vp) : pt(vp[0]) { (valid(e)) \ return tie(x, y, z) == tie(p.x, p.y, p.z);
for (P p : vp) { typedef Point<ll> P; while (circ(e->dir->F(), H(base), e->F())) }
x0 = min(x0, p.x); x1 = max(x1, p.x); typedef struct Quad* Q; { \ P operator+(R p) const { return P(x+p.x, y+p
y0 = min(y0, p.y); y1 = max(y1, p.y); typedef __int128_t lll; // (can be l l i f Q t = e->dir; \ .y, z+p.z); }
} coords are < 2e4) splice(e, e->prev()); \ P operator-(R p) const { return P(x-p.x, y-p
if (vp.size() > 1) { P arb(LLONG_MAX,LLONG_MAX); // not equal to splice(e->r(), e->r()->prev()); \ .y, z-p.z); }
// s p l i t on x i f width >= height (not any other point e->o = H; H = e; e = t; \ P operator*(T d) const { return P(x*d, y*d,
ideal . . . ) } z*d); }
sort(all(vp), x1 - x0 >= y1 - y0 ? on_x struct Quad { for (;;) { P operator/(T d) const { return P(x/d, y/d,
: on_y); Q rot, o; P p = arb; bool mark; DEL(LC, base->r(), o); DEL(RC, base, prev z/d); }
// divide by taking h a l f the array for P& F() { return r()->p; } ()); T dot(R p) const { return x*p.x + y*p.y + z*
each child (not Q& r() { return rot->rot; } if (!valid(LC) && !valid(RC)) break; p.z; }
// best performance with many duplicates Q prev() { return rot->o->rot; } if (!valid(LC) || (valid(RC) && circ(H(RC) P cross(R p) const {
in the middle) Q next() { return r()->prev(); } , H(LC)))) return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p
int half = sz(vp)/2; } *H; base = connect(RC, base->r()); .y - y*p.x);
first = new Node({vp.begin(), vp.begin() else }
+ half}); bool circ(P p, P a, P b, P c) { // i s p in the base = connect(base->r(), LC->r()); T dist2() const { return x*x + y*y + z*z; }
second = new Node({vp.begin() + half, vp circumcircle? } double dist() const { return sqrt((double)
.end()}); lll p2 = p.dist2(), A = a.dist2()-p2, return { ra, rb }; dist2()); }
} B = b.dist2()-p2, C = c.dist2()-p2; } //Azimuthal angle ( longitude ) to x=axis in
} return p.cross(a,b)*C + p.cross(b,c)*A + p. interval [= pi , pi ]
}; cross(c,a)*B > 0; vector<P> triangulate(vector<P> pts) { double phi() const { return atan2(y, x); }
} sort(all(pts)); assert(unique(all(pts)) == //Zenith angle ( l a t i t u d e ) to the z=axis in
struct KDTree { Q makeEdge(P orig, P dest) { pts.end()); interval [0 , pi ]
Node* root; Q r = H ? H : new Quad{new Quad{new Quad{new if (sz(pts) < 2) return {}; double theta() const { return atan2(sqrt(x*x
KDTree(const vector<P>& vp) : root(new Node( Quad{0}}}}; Q e = rec(pts).first; +y*y),z); }
{all(vp)})) {} H = r->o; r->r()->r() = r; vector<Q> q = {e}; P unit() const { return *this/(T)dist(); }
rep(i,0,4) r = r->rot, r->p = arb, r->o = i int qi = 0; //makes d i s t ()=1
pair<T, P> search(Node *node, const P& p) { & 1 ? r : r->r(); while (e->o->F().cross(e->F(), e->p) < 0) e //returns unit vector normal to * t h i s and p
if (!node->first) { r->p = orig; r->F() = dest; = e->o; P normal(P p) const { return cross(p).unit()
// uncomment i f we should not find the return r; #define ADD { Q c = e; do { c->mark = 1; pts. ; }
point i t s e l f : } push_back(c->p); \ //returns point rotated ’ angle ’ radians ccw
// i f (p == node=>pt ) return {INF, P()}; void splice(Q a, Q b) { q.push_back(c->r()); c = c->next(); } while around axis
return make_pair((p - node->pt).dist2(), swap(a->o->rot->o, b->o->rot->o); swap(a->o, (c != e); } P rotate(double angle, P axis) const {
node->pt); b->o); ADD; pts.clear(); double s = sin(angle), c = cos(angle); P u
} } while (qi < sz(q)) if (!(e = q[qi++])->mark) = axis.unit();
Q connect(Q a, Q b) { ADD; return u*dot(u)*(1-c) + (*this)*c - cross(
Node *f = node->first, *s = node->second; Q q = makeEdge(a->F(), b->p); u)*s;
BRACU 3dHull sphericalDistance KMP Zfunc Manacher MinRotation SuffixArray SuffixTree 19
} Description: Returns the shortest distance on the Manacher.h (y[a] == y[b] && y[a + j] == y[b + j])
}; sphere with radius radius between the points with az- Description: For each position in a string, computes ? p - 1 : p++;
imuthal angles (longitude) f1 (ϕ1 ) and f2 (ϕ2 ) from x p[0][i] = half length of longest even palindrome around }
axis and zenith angles (latitude) t1 (θ1 ) and t2 (θ2 ) from pos i, p[1][i] = longest odd (half rounded down). rep(i,1,n) rank[sa[i]] = i;
3dHull.h z axis (0 = north pole). All angles measured in radians. Time: O (N ) e7ad79, 13 lines
for (int i = 0, j; i < n - 1; lcp[rank[i
Description: Computes all faces of the 3-dimension hull The algorithm starts by converting the spherical coordi- ++]] = k)
nates to cartesian coordinates so if that is what you have array<vi, 2> manacher(const string& s) { for (k && k--, j = sa[rank[i] - 1];
of a point set. *No four points must be coplanar*, or else int n = sz(s);
random results will be returned. All faces will point out- you can use only the two last rows. dx*radius is then the s[i + k] == s[j + k]; k++);
difference between the two points in the x direction and array<vi,2> p = {vi(n+1), vi(n)}; }
wards. rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++)
Time: O n2
 d*radius is the total distance between the points.
611f07, 8 lines
};
{
"Point3D.h" 5b45fc, 49 lines double sphericalDistance(double f1, double t1, int t = r-i+!z;
typedef Point3D<double> P3; double f2, double t2, double radius) { if (i<r) p[z][i] = min(t, p[z][l+t]); SuffixTree.h
double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1 int L = i-p[z][i], R = i+p[z][i]-!z; Description: Ukkonen’s algorithm for online suffix tree
struct PR { ); while (L>=1 && R+1<n && s[L-1] == s[R+1]) construction. Each node contains indices [l, r) into the
void ins(int x) { (a == -1 ? a : b) = x; } double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1 p[z][i]++, L--, R++; string, and a list of child nodes. Suffixes are given by
void rem(int x) { (a == x ? a : b) = -1; } ); if (R>r) l=L, r=R; traversals of this tree, joining [l, r) substrings. The root
int cnt() { return (a != -1) + (b != -1); } double dz = cos(t2) - cos(t1); } is 0 (has l = -1, r = 0), non-existent children are -1. To
int a, b; double d = sqrt(dx*dx + dy*dy + dz*dz); return p; get a complete tree, append a dummy symbol – other-
}; return radius*2*asin(d/2); } wise it may contain an incomplete path (still useful for
} substring matching, though).
struct F { P3 q; int a, b, c; }; Time: O (26N )
MinRotation.h aae0b8, 50 lines

vector<F> hull3d(const vector<P3>& A) {


assert(sz(A) >= 4);
Strings (9) Description: Finds the lexicographically smallest rota-
tion of a string.
struct SuffixTree {
enum { N = 200010, ALPHA = 26 }; // N ∼ 2*
vector<vector<PR>> E(sz(A), vector<PR>(sz(A) Usage: rotate(v.begin(), maxlen+10
, {-1, -1})); KMP.h v.begin()+minRotation(v), v.end()); int toi(char c) { return c - ’a’; }
#define E(x,y) E[f.x][f.y] Description: pi[x] computes the length of the longest Time: O (N ) string a; // v = cur node , q = cur position
d07a42, 8 lines
vector<F> FS; prefix of s that ends at x, other than s[0...x] itself (aba- int t[N][ALPHA],l[N],r[N],p[N],s[N],v=0,q=0,
caba -> 0010123). Can be used to find all occurrences of int minRotation(string s) {
auto mf = [&](int i, int j, int k, int l) { m=2;
a string. int a=0, N=sz(s); s += s;
P3 q = (A[j] - A[i]).cross((A[k] - A[i]));
Time: O (n) rep(b,0,N) rep(k,0,N) {
if (q.dot(A[l]) > q.dot(A[i])) d4375c, 16 lines void ukkadd(int i, int c) { suff:
if (a+k == b || s[a+k] < s[b+k]) {b += max
q = q * -1; vi pi(const string& s) { if (r[v]<=q) {
(0, k-1); break;}
F f{q, i, j, k}; vi p(sz(s)); if (t[v][c]==-1) { t[v][c]=m; l[m]=i;
if (s[a+k] > s[b+k]) { a = b; break; }
E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i rep(i,1,sz(s)) { p[m++]=v; v=s[v]; q=r[v]; goto suff;
}
); int g = p[i-1]; }
return a;
FS.push_back(f); while (g && s[i] != s[g]) g = p[g-1]; v=t[v][c]; q=l[v];
}
}; p[i] = g + (s[i] == s[g]); }
rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4) } if (q==-1 || c==toi(a[q])) q++; else {
mf(i, j, k, 6 - i - j - k); return p; SuffixArray.h l[m+1]=i; p[m+1]=m; l[m]=l[v]; r[m]=q
} Description: Builds suffix array for a string. sa[i] is ;
rep(i,4,sz(A)) { the starting index of the suffix which is i’th in the sorted p[m]=p[v]; t[m][c]=m+1; t[m][toi(a[q])
rep(j,0,sz(FS)) { vi match(const string& s, const string& pat) { suffix array. The returned vector is of size n + 1, and ]=v;
F f = FS[j]; vi p = pi(pat + ’\0’ + s), res; sa[0] = n. The lcp array contains longest common pre- l[v]=q; p[v]=m; t[p[m]][toi(a[l[m]])]=
if(f.q.dot(A[i]) > f.q.dot(A[f.a])) { rep(i,sz(p)-sz(s),sz(p)) fixes for neighbouring strings in the suffix array: lcp[i] m;
E(a,b).rem(f.c); if (p[i] == sz(pat)) res.push_back(i - 2 * = lcp(sa[i], sa[i-1]), lcp[0] = 0. The input string v=s[p[m]]; q=l[m];
E(a,c).rem(f.b); sz(pat)); must not contain any zero bytes. while (q<r[m]) { v=t[v][toi(a[q])]; q+=
E(b,c).rem(f.a); return res; Time: O (n log n) r[v]-l[v]; }
swap(FS[j--], FS.back()); 38db9f, 23 lines if (q==r[m]) s[m]=v; else s[m]=m+2;
}
FS.pop_back(); struct SuffixArray { q=r[v]-(q-r[m]); m+=2; goto suff;
} vi sa, lcp; }
} Zfunc.h SuffixArray(string& s, int lim=256) { // or }
int nw = sz(FS); Description: z[x] computes the length of the longest basic string<int>
rep(j,0,nw) { common prefix of s[i:] and s, except z[0] = 0. (abacaba int n = sz(s) + 1, k = 0, a, b; SuffixTree(string a) : a(a) {
F f = FS[j]; -> 0010301) vi x(all(s)+1), y(n), ws(max(n, lim)), fill(r,r+N,sz(a));
#define C(a, b, c) if (E(a,b).cnt() != 2) mf(f Time: O (n) ee09e2, 12 lines rank(n); memset(s, 0, sizeof s);
.a, f.b, i, f.c); sa = lcp = y, iota(all(sa), 0); memset(t, -1, sizeof t);
vi Z(const string& S) {
C(a, b, c); C(a, c, b); C(b, c, a); for (int j = 0, p = 0; p < n; j = max(1, j fill(t[1],t[1]+ALPHA,0);
vi z(sz(S));
} int l = -1, r = -1; * 2), lim = p) { s[0] = 1; l[0] = l[1] = -1; r[0] = r[1] =
} p = j, iota(all(y), n - j); p[0] = p[1] = 0;
rep(i,1,sz(S)) {
for (F& it : FS) if ((A[it.b] - A[it.a]). rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i rep(i,0,sz(a)) ukkadd(i, toi(a[i]));
z[i] = i >= r ? 0 : min(r - i, z[i - l]);
cross( ] - j; }
while (i + z[i] < sz(S) && S[i + z[i]] ==
A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it fill(all(ws), 0);
S[z[i]])
.c, it.b); rep(i,0,n) ws[x[i]]++; // example : find longest common substring (
z[i]++;
return FS; rep(i,1,lim) ws[i] += ws[i - 1]; uses ALPHA = 28)
if (i + z[i] > r)
}; for (int i = n; i--;) sa[--ws[x[y[i]]]] pii best;
l = i, r = i + z[i];
= y[i]; int lcs(int node, int i1, int i2, int olen)
}
swap(x, y), p = 1, x[sa[0]] = 0; {
return z;
sphericalDistance.h rep(i,1,n) a = sa[i - 1], b = sa[i], x[b if (l[node] <= i1 && i1 < r[node]) return
}
] = 1;
BRACU Hashing AhoCorasick IntervalContainer IntervalCover ConstantIntervals 20
if (l[node] <= i2 && i2 < r[node]) return h = h * C + str[i], pw = pw * C; (N[ed].end == -1 ? N[ed].end : backp auto r2 = it->second;
2; vector<H> ret = {h}; [N[ed].start]) if (it->first == L) is.erase(it);
int mask = 0, len = node ? olen + (r[node] rep(i,length,sz(str)) { = N[y].end; else (int&)it->second = L;
- l[node]) : 0; ret.push_back(h = h * C + str[i] - pw * N[ed].nmatches += N[y].nmatches; if (R != r2) is.emplace(R, r2);
rep(c,0,ALPHA) if (t[node][c] != -1) str[i-length]); q.push(ed); }
mask |= lcs(t[node][c], i1, i2, len); } }
if (mask == 3) return ret; }
best = max(best, {len, r[node] - len}); } } IntervalCover.h
return mask; } Description: Compute indices of smallest set of inter-
} H hashString(string& s){H h{}; for(char c:s) h vi find(string word) { vals covering another interval. Intervals should be [inclu-
static pii LCS(string s, string t) { =h*C+c;return h;} int n = 0; sive, exclusive). To support [inclusive, inclusive], change
SuffixTree st(s + (char)(’z’ + 1) + t + ( vi res; // l l count = 0; (A) to add || R.empty(). Returns empty set on failure
char)(’z’ + 2)); for (char c : word) { (or if G is empty).
st.lcs(0, sz(s), sz(s) + 1 + sz(t), 0); AhoCorasick.h n = N[n].next[c - first]; Time: O (N log N )
return st.best; Description: Aho-Corasick automaton, used for mul- res.push_back(N[n].end); 9e9d8d, 19 lines
} tiple pattern matching. Initialize with AhoCorasick // count += N[n ] . nmatches ; template<class T>
}; ac(patterns); the automaton start node will be at index } vi cover(pair<T, T> G, vector<pair<T, T>> I) {
0. find(word) returns for each position the index of the return res; vi S(sz(I)), R;
longest word that ends there, √ or -1 if none. findAll(−, } iota(all(S), 0);
Hashing.h word) finds all words (up to N N many if no duplicate vector<vi> findAll(vector<string>& pat, sort(all(S), [&](int a, int b) { return I[a]
Description: Self-explanatory methods for string hash- patterns) that start at each position (shortest first). Du- string word) { < I[b]; });
ing. 2d2a67, 44 lines
plicate patterns are allowed; empty patterns are not. To vi r = find(word); T cur = G.first;
find the longest words that start at each position, re- vector<vi> res(sz(word)); int at = 0;
// Arithmetic mod 2^64=1. 2x slower than mod 2 verse all input. For large alphabets, split each symbol rep(i,0,sz(word)) { while (cur < G.second) { // (A)
^64 and more into chunks, with sentinel bits for symbol boundaries. int ind = r[i]; pair<T, int> mx = make_pair(cur, -1);
// code , but works on e v i l t e s t data (e . g . Time: construction takes O (26N ), where N = sum of while (ind != -1) { while (at < sz(I) && I[S[at]].first <= cur
Thue=Morse, where length of patterns. find(x) is O (N ), where N = length res[i - sz(pat[ind]) + 1].push_back( ) {
// ABBA. . . and BAAB. . . of length 2^10 hash the of x. findAll is O (N M ). ind); mx = max(mx, make_pair(I[S[at]].second,
same mod 2^64) . f35677, 66 lines
ind = backp[ind]; S[at]));
// ”typedef u l l H;” instead i f you think t e s t struct AhoCorasick { } at++;
data i s random, enum {alpha = 26, first = ’A’}; // change } }
// or work mod 10^9+7 i f the Birthday paradox this ! return res; if (mx.second == -1) return {};
i s not a problem . struct Node { } cur = mx.first;
typedef uint64_t ull; // (nmatches i s optional ) }; R.push_back(mx.second);
struct H { int back, next[alpha], start = -1, end = }
ull x; H(ull x=0) : x(x) {} -1, nmatches = 0; return R;
H operator+(H o) { return x + o.x + (x + o.x Node(int v) { memset(next, v, sizeof(next)
< x); } ); } Various (10) }
H operator-(H o) { return *this + ∼o.x; } };
H operator*(H o) { auto m = (__uint128_t)x * vector<Node> N;
o.x; vi backp; 10.1 Intervals ConstantIntervals.h
return H((ull)m) + (ull)(m >> 64); } void insert(string& s, int j) { Description: Split a monotone function on [from, to)
IntervalContainer.h into a minimal set of half-open intervals on which it has
ull get() const { return x + !∼x; } assert(!s.empty()); Description: Add and remove intervals from a set of
bool operator==(H o) const { return get() == int n = 0; the same value. Runs a callback g for each such interval.
disjoint intervals. Will merge the added interval with
o.get(); } for (char c : s) { Usage: constantIntervals(0, sz(v), [&](int
any overlapping intervals in the set when adding. Inter-
bool operator<(H o) const { return get() < o int& m = N[n].next[c - first]; x){return v[x];}, [&](int lo, int hi, T
vals are [inclusive, exclusive).
.get(); } if (m == -1) { n = m = sz(N); N. val){...});
Time: O (log N )
Time: O k log n

}; emplace_back(-1); } edce47, 23 lines
k 753a4c, 19 lines
static const H C = (ll)1e11+3; // (order ∼ 3e9 else n = m; set<pii>::iterator addInterval(set<pii>& is,
template<class F, class G, class T>
; random also ok) } int L, int R) {
void rec(int from, int to, F& f, G& g, int& i,
if (N[n].end == -1) N[n].start = j; if (L == R) return is.end();
T& p, T q) {
struct HashInterval { backp.push_back(N[n].end); auto it = is.lower_bound({L, R}), before =
if (p == q) return;
vector<H> ha, pw; N[n].end = j; it;
if (from == to) {
HashInterval(string& str) : ha(sz(str)+1), N[n].nmatches++; while (it != is.end() && it->first <= R) {
g(i, to, p);
pw(ha) { } R = max(R, it->second);
i = to; p = q;
pw[0] = 1; AhoCorasick(vector<string>& pat) : N(1, -1) before = it = is.erase(it);
} else {
rep(i,0,sz(str)) { }
int mid = (from + to) >> 1;
ha[i+1] = ha[i] * C + str[i], rep(i,0,sz(pat)) insert(pat[i], i); if (it != is.begin() && (--it)->second >= L)
rec(from, mid, f, g, i, p, f(mid));
pw[i+1] = pw[i] * C; N[0].back = sz(N); {
rec(mid+1, to, f, g, i, p, q);
} N.emplace_back(0); L = min(L, it->first);
}
H hashInterval(int a, int b) { // hash [ a , b R = max(R, it->second);
}
) queue<int> q; is.erase(it);
template<class F, class G>
return ha[b] - ha[a] * pw[b - a]; for (q.push(0); !q.empty(); q.pop()) { }
void constantIntervals(int from, int to, F f,
} int n = q.front(), prev = N[n].back; return is.insert(before, {L,R});
G g) {
}; rep(i,0,alpha) { }
if (to <= from) return;
int &ed = N[n].next[i], y = N[prev].
int i = from; auto p = f(i), q = f(to-1);
vector<H> getHashes(string& str, int length) { next[i]; void removeInterval(set<pii>& is, int L, int R
rec(from, to-1, f, g, i, p, q);
if (sz(str) < length) return {}; if (ed == -1) ed = y; ) {
g(i, to, q);
H h = 0, pw = 1; else { if (L == R) return;
}
rep(i,0,length) N[ed].back = y; auto it = addInterval(is, L, R);
BRACU TernarySearch LIS FastKnapsack KnuthDP DivideAndConquerDP FastMod FastInput BumpAllocator SmallPtr BumpAllocatorSTL 21
10.2 Misc. algorithms for (x = 2*m; --x > m;) rep(j, max(0,u[x]) ˆ feenableexcept(29); kills the Time: About 5x as fast as cin/scanf. 7b3c70, 17 lines
, v[x]) program on NaNs (1), 0-divs (4), infinities
TernarySearch.h v[x-w[j]] = max(v[x-w[j]], j); inline char gc() { // l i k e getchar ()
Description: Find the smallest i in [a, b] that maximizes (8) and denormals (16). static char buf[1 << 16];
}
f (i), assuming that f (a) < . . . < f (i) ≥ · · · ≥ f (b). To static size_t bc, be;
for (a = t; v[a+m-t] < 0; a--) ;
reverse which of the sides allows non-strict inequalities,
change the < marked with (A) to <=, and reverse the
return a; 10.5 Optimization tricks if (bc >= be) {
buf[0] = 0, bc = 0;
}
loop at (B). To minimize f , change it to >, also at (B). __builtin_ia32_ldmxcsr(40896); disables be = fread(buf, 1, sizeof(buf), stdin);
Usage: int ind = ternSearch(0,n-1,[&](int denormals (which make floats 20x slower near }
i){return a[i];}); return buf[bc++]; // returns 0 on EOF
Time: O (log(b − a)) 10.3 Dynamic their minimum value). }
9155b4, 11 lines

template<class F> programming 10.5.1 Bit hacks int readInt() {


int ternSearch(int a, int b, F f) {
KnuthDP.h int a, c;
assert(a <= b); ˆ x & -x is the least bit in x. while ((a = gc()) < 40);
while (b - a >= 5) { Description: When doing DP on intervals: a[i][j] =
if (a == ’-’) return -readInt();
int mid = (a + b) / 2; mini<k<j (a[i][k] + a[k][j]) + f (i, j), where the (minimal)
optimal k increases with both i and j, one can solve inter-
ˆ while ((c = gc()) >= 48) a = a * 10 + c -
if (f(mid) < f(mid+1)) a = mid; // (A)
else b = mid+1; vals in increasing order of length, and search k = p[i][j] for (int x = m; x; ) { --x &= m; ... } 480;
for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This return a - 48;
} loops over all subset masks of m (except m }
rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B is known as Knuth DP. Sufficient criteria for this are if
f (b, c) ≤ f (a, d) and f (a, c) + f (b, d) ≤ f (a, d) + f (b, c)
itself).
)
return a; for all a ≤ b ≤ c ≤ d. Consider also: LineContainer (ch.
ˆ
BumpAllocator.h
} Data structures), monotone queues, ternary search. Description: When you need to dynamically allocate
Time: O N 2 c = x&-x, r = x+c; (((rˆx) >> 2)/c) | r
many objects and don’t care about freeing them. ”new
is the next number after x with the same X” otherwise has an overhead of something like 0.05us +
LIS.h 16 bytes per allocation. 745db2, 8 lines
Description: Compute indices for the longest increas- number of bits set.
ing subsequence. DivideAndConquerDP.h // Either g l o b a l l y or in a single class :
Time: O (N log N ) 2932a0, 17 lines Description: Given a[i] = minlo(i)≤k<hi(i) (f (i, k)) ˆ rep(b,0,K) rep(i,0,(1 << K)) static char buf[450 << 20];
where the (minimal) optimal k increases with i, com- void* operator new(size_t s) {
template<class I> vi lis(const vector<I>& S) {
putes a[i] for i = L..R − 1.
if (i & 1 << b) D[i] += D[iˆ(1 << static
b)]; size_t i = sizeof buf;
if (S.empty()) return {}; computes all sums of subsets. assert(s < i);
Time: O ((N + (hi − lo)) log N )
vi prev(sz(S)); d38d2b, 18 lines
return (void*)&buf[i -= s];
typedef pair<I, int> p; struct DP { // Modify at w i l l : 10.5.2 Pragmas }
vector<p> res; int lo(int ind) { return 0; } void operator delete(void*) {}
rep(i,0,sz(S)) { int hi(int ind) { return ind; } ˆ #pragma GCC optimize ("Ofast") will make
// change 0 => i for longest non= ll f(int ind, int k) { return dp[ind][k]; }
decreasing subsequence void store(int ind, int k, ll v) { res[ind]
GCC auto-vectorize loops and optimizes SmallPtr.h
auto it = lower_bound(all(res), p{S[i], 0} = pii(k, v); } floating points better. Description: A 32-bit pointer that points into BumpAl-
); locator memory.
if (it == res.end()) res.emplace_back(), void rec(int L, int R, int LO, int HI) { ˆ #pragma GCC target ("avx2") can double "BumpAllocator.h" 2dd6c9, 10 lines
it = res.end()-1; if (L >= R) return; template<class T> struct ptr {
*it = {S[i], i};
performance of vectorized code, but causes unsigned ind;
int mid = (L + R) >> 1;
prev[i] = it == res.begin() ? 0 : (it-1)-> pair<ll, int> best(LLONG_MAX, LO); crashes on old machines. ptr(T* p = 0) : ind(p ? unsigned((char*)p -
second; rep(k, max(LO,lo(mid)), min(HI,hi(mid))) buf) : 0) {
} best = min(best, make_pair(f(mid, k), k) ˆ #pragma GCC optimize ("trapv") kills the assert(ind < sizeof buf);
int L = sz(res), cur = res.back().second; ); }
vi ans(L);
program on integer overflows (but is really T& operator*() const { return *(T*)(buf +
store(mid, best.second, best.first);
while (L--) ans[L] = cur, cur = prev[cur]; rec(L, mid, LO, best.second+1); slow). ind); }
return ans; rec(mid+1, R, best.second, HI); T* operator->() const { return &**this; }
} } FastMod.h T& operator[](int a) const { return (&**this
void solve(int L, int R) { rec(L, R, INT_MIN Description: Compute a%b about 5 times faster than )[a]; }
, INT_MAX); } usual, where b is constant but not known at compile explicit operator bool() const { return ind;
FastKnapsack.h }; time. Returns a value congruent to a (mod b) in the }
Description: Given N non-negative integer weights w
range [0, 2b). };
and a non-negative target t, computes the maximum S 751a02, 8 lines
<= t such that S is the sum of some subset of the weights. typedef unsigned long long ull;
Time: O (N max(wi )) b20ccc, 16 lines 10.4 Debugging tricks struct FastMod { BumpAllocatorSTL.h
ull b, m; Description: BumpAllocator for STL containers.
int knapsack(vi w, int t) { Usage: vector<vector<int, small<int>>>
FastMod(ull b) : b(b), m(-1ULL / b) {}
int a = 0, b = 0, x; ˆ ull reduce(ull a) { // a % b + (0 or b) ed(N); bb66d4, 14 lines
while (b < sz(w) && a + w[b] <= t) a += w[b
signal(SIGSEGV, [](int) { _Exit(0); }); return a - (ull)((__uint128_t(m) * a) >>
++]; char buf[450 << 20] alignas(16);
64) * b;
if (b == sz(w)) return a; converts segfaults into Wrong Answers. }
size_t buf_ind = sizeof buf;
int m = *max_element(all(w));
vi u, v(2*m, -1);
Similarly one can catch SIGABRT };
template<class T> struct small {
v[a+m-t] = b; (assertion failures) and SIGFPE (zero typedef T value_type;
rep(i,b,sz(w)) { divisions). _GLIBCXX_DEBUG failures FastInput.h small() {}
u = v; Description: Read an integer from stdin. Usage re- template<class U> small(const U&) {}
rep(x,0,m) v[x+w[i]] = max(v[x+w[i]], u[x generate SIGABRT (or SIGSEGV on gcc quires your program to pipe in input from file. T* allocate(size_t n) {
]); 5.4.0 apparently). Usage: ./a.out < input.txt buf_ind -= n * sizeof(T);
BRACU SIMD 22
buf_ind &= 0 - alignof(T); mi zero = _mm256_setzero_si256(), acc = zero
return (T*)(buf + buf_ind); ;
} while (i + 16 <= n) {
void deallocate(T*, size_t) {} mi va = L(a[i]), vb = L(b[i]); i += 16;
}; va = _mm256_and_si256(_mm256_cmpgt_epi16(
vb, va), va);
mi vp = _mm256_madd_epi16(va, vb);
acc = _mm256_add_epi64(
SIMD.h _mm256_unpacklo_epi32(vp, zero),
Description: Cheat sheet of SSE/AVX intrinsics, for _mm256_add_epi64(acc,
doing arithmetic on several numbers at once. Can _mm256_unpackhi_epi32(vp, zero)));
provide a constant factor improvement of about 4, or- }
thogonal to loop unrolling. Operations follow the pattern union {ll v[4]; mi m;} u; u.m = acc; rep(i
" mm(256)? name (si(128|256)|epi(8|16|32|64)|pd|ps)". ,0,4) r += u.v[i];
Not all are described here; grep for mm in for (;i<n;++i) if (a[i] < b[i]) r += a[i]*b[
/usr/lib/gcc/*/4.9/include/ for more. If AVX i]; // <= equiv
is unsupported, try 128-bit operations, ”emmintrin.h” return r;
and #define SSE and MMX before including it. }
For aligned memory use mm malloc(size, 32) or int
buf[N] alignas(32), but prefer loadu/storeu.551b82, 43 lines
#pragma GCC target ("avx2") // or sse4 .1
#include "immintrin.h"

typedef __m256i mi;


#define L(x) _mm256_loadu_si256((mi*)&(x))

// 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
// blendv ( epi8 | ps | pd) ( z?y : x) , movemask epi8
( h i b i t s of bytes )
// i32gather epi32 (addr , x , 4) : map addr [ ]
over 32=b parts of x
// sad epu8 : sum of absolute differences of u8
, outputs 4xi64
// maddubs epi16 : dot product of unsigned i7 ’ s
, outputs 16xi15
// madd epi16 : dot product of signed i16 ’ s ,
outputs 8xi32
// extractf128 si256 ( , i ) (256=>128) ,
cvtsi128 si32 (128=>lo32 )
// permute2f128 si256(x , x ,1) swaps 128= b i t
lanes
// shuffle epi32 (x , 3*64+2*16+1*4+0) == x for
each lane
// s h u f f l e e p i 8 (x , y) takes a vector instead
of an imm

// Methods that work with most data types (


append e . g . epi32 ) :
// set1 , blend ( i8?x : y) , add , adds ( sat . ) ,
mullo , sub , and/or ,
// andnot , abs , min, max, sign (1 ,x) , cmp( gt | eq
) , unpack( lo | hi )

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; }
mi zero() { return _mm256_setzero_si256(); }
mi one() { return _mm256_set1_epi32(-1); }
bool all_zero(mi m) { return
_mm256_testz_si256(m, m); }
bool all_one(mi m) { return _mm256_testc_si256
(m, one()); }

ll example_filteredDotProduct(int n, short* a,
short* b) {
int i = 0; ll r = 0;
BRACU techniques 23

Techniques (A) Computation of binomial coefficients


Pigeon-hole principle
Knuth-Morris-Pratt
Tries
Inclusion/exclusion Rolling polynomial hashes
techniques.txt 159 lines
Catalan number Suffix array
Pick’s theorem Suffix tree
Recursion Number theory Aho-Corasick
Divide and conquer Integer parts Manacher’s algorithm
Finding interesting points in N log N Divisibility Letter position lists
Algorithm analysis Euclidean algorithm Combinatorial search
Master theorem Modular arithmetic Meet in the middle
Amortized time complexity
Greedy algorithm * Modular multiplication Brute-force with pruning
Scheduling * Modular inverses Best-first (A*)
Max contiguous subvector sum * Modular exponentiation by squaring Bidirectional search
Chinese remainder theorem Iterative deepening DFS / A*
Invariants Fermat’s little theorem Data structures
Huffman encoding Euler’s theorem LCA (2^k-jumps in trees in general)
Graph theory Phi function Pull/push-technique on trees
Dynamic graphs (extra book-keeping) Frobenius number Heavy-light decomposition
Breadth first search Quadratic reciprocity Centroid decomposition
Depth first search Pollard-Rho Lazy propagation
* Normal trees / DFS trees Miller-Rabin Self-balancing trees
Dijkstra’s algorithm Hensel lifting Convex hull trick (wcipeg.com/wiki/Convex_hull_trick)
MST: Prim’s algorithm Vieta root jumping Monotone queues / monotone stacks / sliding queues
Bellman-Ford Game theory Sliding queue using 2 stacks
Konig’s theorem and vertex cover Combinatorial games Persistent segment tree
Min-cost max flow Game trees
Lovasz toggle Mini-max
Matrix tree theorem Nim
Maximal matching, general graphs Games on graphs
Hopcroft-Karp Games on graphs with loops
Hall’s marriage theorem Grundy numbers
Graphical sequences Bipartite games without repetition
Floyd-Warshall General games without repetition
Euler cycles Alpha-beta pruning
Flow networks Probability theory
* Augmenting paths Optimization
* Edmonds-Karp Binary search
Bipartite matching Ternary search
Min. path cover Unimodality and convex functions
Topological sorting Binary search on derivative
Strongly connected components Numerical methods
2-SAT Numeric integration
Cut vertices, cut-edges and biconnected components Newton’s method
Edge coloring Root-finding with binary/ternary search
* Trees Golden section search
Vertex coloring Matrices
* Bipartite graphs (=> trees) Gaussian elimination
* 3^n (special case of set cover) Exponentiation by squaring
Diameter and centroid Sorting
K’th shortest path Radix sort
Shortest cycle Geometry
Dynamic programming Coordinates and vectors
Knapsack
Coin change * Cross product
Longest common subsequence * Scalar product
Convex hull
Longest increasing subsequence Polygon cut
Number of paths in a dag Closest pair
Shortest path in a dag Coordinate-compression
Dynprog over intervals Quadtrees
Dynprog over subsets KD-trees
Dynprog over probabilities All segment-segment intersection
Dynprog over trees Sweeping
3^n set cover Discretization (convert to events and sweep)
Divide and conquer Angle sweeping
Knuth optimization Line sweeping
Convex hull optimizations Discrete second derivatives
RMQ (sparse table a.k.a 2^k-jumps) Strings
Bitonic cycle Longest common substring
Log partitioning (loop over most restricted) Palindrome subsequences
Combinatorics

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy