0% found this document useful (0 votes)
71 views26 pages

Uet Awk

The document appears to be a collection of notes and guidelines related to programming contests, mathematics, and algorithms. It includes troubleshooting tips for common coding issues, mathematical formulas, and programming constructs. Additionally, it covers various mathematical concepts such as geometry, probability theory, and numerical methods.

Uploaded by

teamliquid31211
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)
71 views26 pages

Uet Awk

The document appears to be a collection of notes and guidelines related to programming contests, mathematics, and algorithms. It includes troubleshooting tips for common coding issues, mathematical formulas, and programming constructs. Additionally, it covers various mathematical concepts such as geometry, probability theory, and numerical methods.

Uploaded by

teamliquid31211
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/ 26

University of Engineering and Technology,

Vietnam National University

AWK
Nhà E3, 144 Xuân Thủy, quận Cầu Giấy,
Hà Nội,
Việt Nam

2023-12-07
1 Contest 1 troubleshoot.txt 52 lines
ed − bf
Pre-submit:
ax + by = e x=
2 Mathematics 1 Write a few simple test cases if sample is not enough. ad − bc

Are time limits close? If so, generate max cases. cx + dy = f af − ec
Is the memory usage fine? y=
3 Data structures 3 Could anything overflow? ad − bc
Make sure to submit the right file.
In general, given an equation Ax = b, the solution to a variable
4 Numerical 5 Wrong answer: xi is given by
Print your solution! Print debug output, as well.
Are you clearing all data structures between test cases?
det A0i
5 Number theory 8 xi =
Can your algorithm handle the whole range of input? det A
Read the full problem statement again. 0
6 Combinatorial 10 Do you handle all corner cases correctly? where Ai is A with the i’th column replaced by b.
Have you understood the problem correctly?

7 Graph 11
Any uninitialized variables?
Any overflows?
2.2 Recurrences
Confusing N and M, i and j, etc.?
Are you sure your algorithm works?
If an = c1 an−1 + · · · + ck an−k , and r1 , . . . , rk are distinct roots of
8 Geometry 17 What special cases have you not thought of? xk + c1 xk−1 + · · · + ck , there are d1 , . . . , dk s.t.
Are you sure the STL functions you use work as you think?
9 Strings 21 Add some assertions, maybe resubmit. an = d1 r1n + · · · + dk rkn .
Create some testcases to run your algorithm on.
Go through the algorithm for a simple case.
10 Various 22 Go through this list again. Non-distinct roots r become polynomial factors, e.g.
Explain your algorithm to a teammate. an = (d1 n + d2 )rn .
Ask the teammate to look at your code.
Contest (1) Go for a small walk, e.g. to the toilet.
Is your output format correct? (including whitespace) 2.3 Trigonometry
Rewrite your solution from the start or let a teammate do it.
template.cpp 14 lines sin(v + w) = sin v cos w + cos v sin w
Runtime error:
#include <bits/stdc++.h> Have you tested all corner cases locally?
using namespace std; Any uninitialized variables?
cos(v + w) = cos v cos w − sin v sin w
Are you reading or writing outside the range of any vector?
#define rep(i, a, b) for(int i = a; i < (b); ++i) Any assertions that might fail?
#define all(x) begin(x), end(x) Any possible division by 0? (mod 0 for example)
#define sz(x) (int)(x).size() Any possible infinite recursion?
typedef long long ll; tan v + tan w
Invalidated pointers or iterators? tan(v + w) =
typedef pair<int, int> pii; Are you using too much memory? 1 − tan v tan w
typedef vector<int> vi; Debug with resubmits (e.g. remapped signals, see Various). v+w v−w
sin v + sin w = 2 sin cos
int main() { Time limit exceeded: 2 2
cin.tie(0)->sync_with_stdio(0); Do you have any possible infinite loops? v+w v−w
cin.exceptions(cin.failbit); What is the complexity of your algorithm? cos v + cos w = 2 cos cos
}
2 2
Are you copying a lot of unnecessary data? (References)
How big is the input and output? (consider scanf) (V + W ) tan(v − w)/2 = (V − W ) tan(v + w)/2
Avoid vector, map. (use arrays/unordered_map)
.bashrc 3 lines What do your teammates think about your algorithm? where V, W are lengths of sides opposite angles v, w.
alias c=’g++ -Wall -Wconversion -Wfatal-errors -g -std=c++14 \
Memory limit exceeded:
-fsanitize=undefined,address’
What is the max amount of memory your algorithm should need?
a cos x + b sin x = r cos(x − φ)
xmodmap -e ’clear lock’ -e ’keycode 66=less greater’ #caps = <>
Are you clearing all data structures between test cases? a sin x + b cos x = r sin(x + φ)
.vimrc √
6 lines where r = a2 + b2 , φ = atan2(b, a).
set cin aw ai is ts=4 sw=4 tm=50 nu noeb bg=dark ru cul Mathematics (2)
sy on | im jk <esc> | im kj <esc> | no ; :
" Select region and then type :Hash to hash your selection. 2.4 Geometry
" Useful for verifying that there aren’t mistypes. 2.1 Equations
ca Hash w !cpp -dD -P -fpreprocessed \| tr -d ’[:space:]’ \ 2.4.1 Triangles
\| md5sum \| cut -c-6
√ Side lengths: a, b, c
2 −b ± b2 − 4ac a+b+c
hash.sh ax + bx + c = 0 ⇒ x = Semiperimeter: p =
3 lines 2a 2
p
# Hashes a file, ignoring all whitespace and comments. Use for Area: A = p(p − a)(p − b)(p − c)
# verifying that code was correctly typed.
cpp -dD -P -fpreprocessed | tr -d ’[:space:]’| md5sum |cut -c-6 abc
The extremum is given by x = −b/2a. Circumradius: R =
4A
KTH template .bashrc .vimrc hash troubleshoot 2
A Integration by parts: 2.8.1 Discrete distributions
Inradius: r =
p
Binomial distribution
Z b b
Length √of median (divides triangle into two equal-area triangles):
Z
ma = 21 2b2 + 2c2 − a2 f (x)g(x)dx = [F (x)g(x)]ba − F (x)g 0 (x)dx
a a
Length The number of successes in n independent yes/no experiments,
v of "bisector (divides angles in two):
u 2 # each which yields success with probability p is
2.6 Sums

u a Bin(n, p), n = 1, 2, . . . , 0 ≤ p ≤ 1.
sa = tbc 1 −
b+c
cb+1 − ca
!
sin α sin β sin γ 1 ca + ca+1 + · · · + cb = , c 6= 1 p(k) =
n k
p (1 − p)n−k
Law of sines: = = = c−1 k
a b c 2R
Law of cosines: a2 = b2 + c2 − 2bc cos α
α+β n(n + 1) µ = np, σ 2 = np(1 − p)
tan 1 + 2 + 3 + ··· + n =
a+b 2 2 Bin(n, p) is approximately Po(np) for small p.
Law of tangents: = n(2n + 1)(n + 1)
a−b α−β 2 2 2 2
tan 1 + 2 + 3 + ··· + n =
2 6 First success distribution
3 3 3 3 n2 (n + 1)2
2.4.2 Quadrilaterals 1 + 2 + 3 + ··· + n =
4 The number of trials needed to get the first success in
With side lengths a, b, c, d, diagonals e, f , diagonals angle θ, area 4 4 4 4 n(n + 1)(2n + 1)(3n2 + 3n − 1) independent yes/no experiments, each wich yields success with
1 + 2 + 3 + ··· + n = probability p is Fs(p), 0 ≤ p ≤ 1.
A and magic flux F = b2 + d2 − a2 − c2 : 30
p(k) = p(1 − p)k−1 , k = 1, 2, . . .
p
4A = 2ef · sin θ = F tan θ = 4e2 f 2 − F 2 1 2 1−p
µ= ,σ =
2.7 Series p p2

For cyclic quadrilateralspthe sum of opposite angles is 180 , x2 x3 Poisson distribution
ex = 1 + x + + + . . . , (−∞ < x < ∞)
ef = ac + bd, and A = (p − a)(p − b)(p − c)(p − d). 2! 3!
The number of events occurring in a fixed period of time t if these
2.4.3 Spherical coordinates x2 x3 x4 events occur with a known average rate κ and independently of
ln(1 + x) = x − + − + . . . , (−1 < x ≤ 1)
2 3 4 the time since the last event is Po(λ), λ = tκ.
z √ x x2 2x3 5x4 λk
1+x=1+ − + − + . . . , (−1 ≤ x ≤ 1) p(k) = e−λ
r 2 8 32 128 k!
, k = 0, 1, 2, . . .
y x3 x5 x7
sin x = x − + − + . . . , (−∞ < x < ∞) µ = λ, σ 2 = λ
3! 5! 7!
x x2 x4 x6 2.8.2 Continuous distributions
cos x = 1 − + − + . . . , (−∞ < x < ∞)
2! 4! 6! Uniform distribution
p
x = r sin θ cos φ r = xp 2 + y2 + z2

y = r sin θ sin φ θ = acos(z/ x2 + y 2 + z 2 ) 2.8 Probability theory If the probability density function is constant between a and b
z = r cos θ φ = atan2(y, x) and 0 elsewhere it is U(a, b), a < b.
Let X be a discrete random variable with probability pX (x) of
 1
assuming theP value x. It will then have an expected value (mean) b−a
a<x<b
f (x) =
2.5 Derivatives/Integrals µ = E(X) = x xpX (x) and variance 0 otherwise
σ 2 = V (X) = E(X 2 ) − (E(X))2 = x (x − E(X))2 pX (x) where σ
P
is the standard deviation. If X is instead continuous it will have a+b 2 (b − a)2
µ= ,σ =
d 1 d 1 a probability density function fX (x) and the sums above will 2 12
arcsin x = √ arccos x = − √
dx 1 − x2 dx 1 − x2 instead be integrals with pX (x) replaced by fX (x). Exponential distribution
d d 1 Expectation is linear:
tan x = 1 + tan2 x arctan x = The time between events in a Poisson process is
dx dx 1 + x2
Z
ln | cos ax|
Z
sin ax − ax cos ax E(aX + bY ) = aE(X) + bE(Y ) Exp(λ), λ > 0.
tan ax = − λe−λx x ≥ 0

x sin ax =
a a2 f (x) =
Z √ Z ax For independent X and Y , 0 x<0
2 π e
e−x = erf(x) xeax dx = 2 (ax − 1) 1 2 1
2 a V (aX + bY ) = a2 V (X) + b2 V (Y ). µ= ,σ = 2
λ λ
KTH OrderStatisticTree HashMap SegmentTreeBeat 3
Normal distribution using Tree = tree<T, null_type, less<T>, rb_tree_tag, void down(int id, int l, int r){
tree_order_statistics_node_update>; int t = lazy[id];
lazy[id] = 0;
Most real random values with mean µ and variance σ 2 are well void example() {
int mid = (l + r) / 2;
st[id * 2] += t * (mid - l + 1);
described by N (µ, σ 2 ), σ > 0. Tree<int> t, t2; t.insert(8); st[id * 2 + 1] += t * (r - mid);
auto it = t.insert(10).first; lazy[id * 2] += t;
(x−µ)2 assert(it == t.lower_bound(9)); lazy[id * 2 + 1] += t;
1 − _max[id * 2] += t;
f (x) = √ e 2σ2 assert(t.order_of_key(10) == 1);
2πσ 2 assert(t.order_of_key(11) == 2); _max[id * 2 + 1] += t;
_min[id * 2] += t;
assert(*t.find_by_order(0) == 8); _min[id * 2 + 1] += t;
If X1 ∼ N (µ1 , σ12 ) and X2 ∼ N (µ2 , σ22 ) then t.join(t2); // assuming T < T2 or T > T2, merge t2 into t if(_semax[id * 2] != -oo) _semax[id * 2] += t;
} if(_semax[id * 2 + 1] != -oo) _semax[id * 2 + 1] += t;
if(_semin[id * 2] != oo) _semin[id * 2] += t;
aX1 + bX2 + c ∼ N (µ1 + µ2 + c, a2 σ12 + b2 σ22 ) if(_semin[id * 2 + 1] != oo) _semin[id * 2 + 1] += t;
HashMap.h int val = _max[id];
Description: Hash map with mostly the same API as unordered map, but if(_max[id * 2] > val){
∼3x faster. Uses 1.5x memory. Initial capacity must be a power of 2 (if st[id * 2] -= cntmax[id * 2] * (_max[id * 2] - val);
2.9 Markov chains provided). d77092, 7 lines
_max[id * 2] = val;
if(l == mid) _min[id * 2] = val;
A Markov chain is a discrete random process with the property #include <bits/extc++.h> else{
// To use most b i t s rather than j u s t the lowest ones : if(_min[id * 2] > val) _min[id * 2] = val;
that the next state depends only on the current state. Let struct chash { // large odd number for C else if(_semin[id * 2] > val) _semin[id * 2] = val;
const uint64_t C = ll(4e18 * acos(0)) | 71; }
X1 , X2 , . . . be a sequence of random variables generated by the }
ll operator()(ll x) const { return __builtin_bswap64(x*C); }
Markov process. Then there is a transition matrix P = (pij ), if(_max[id * 2 + 1] > val){
}; st[id * 2 + 1] -= cntmax[id * 2 + 1] * (_max[id * 2 + 1] - val);
with pij = Pr(Xn = i|Xn−1 = j), and p(n) = Pn p(0) is the __gnu_pbds::gp_hash_table<ll,int,chash> h({},{},{},{},{1<<16}); _max[id * 2 + 1] = val;
(n) if(mid + 1 == r) _min[id * 2 + 1] = val;
probability distribution for Xn (i.e., pi = Pr(Xn = i)), where else{
(0)
p is the initial distribution. SegmentTreeBeat.h if(_min[id * 2 + 1] > val) _min[id * 2 + 1] = val;
Description: Zero-indexed max-tree. Bounds are inclusive to the left and else if(_semin[id * 2 + 1] > val) _semin[id * 2 + 1] = val;
exclusive to the right. Can be changed by modifying T, f and unit. }
π is a stationary distribution if π = πP. If the Markov chain is Time: O (log N ) }
0f4bdb, 19 lines
irreducible (it is possible to get to any state from any state), then struct SegtreeBeats{
val = _min[id];
if(_min[id * 2] < val){
πi = E(T1 i ) where E(Ti ) is the expected time between two visits in int _min[4 * maxN], _semin[4 * maxN], _max[4 * maxN], _semax[4 * maxN];
st[id * 2] += cntmin[id * 2] * (val - _min[id * 2]);
int cntmin[4 * maxN], cntmax[4 * maxN], st[4 * maxN], lazy[4 * maxN];
state i. πj /πi is the expected number of visits in state j between _min[id * 2] = val;
void reset(){
if(l == mid) _max[id * 2] = val;
two visits in state i. memset(st, 0, sizeof st);
else{
memset(lazy, 0, sizeof lazy);
if(_max[id * 2] < val) _max[id * 2] = val;
memset(_min, 0, sizeof _min);
For a connected, undirected and non-bipartite graph, where the else if(_semax[id * 2] < val) _semax[id * 2] = val;
memset(_max, 0, sizeof _max);
}
transition probability is uniform among all neighbors, πi is memset(_semin, 0, sizeof _semin);
}
memset(_semax, 0, sizeof _semax);
proportional to node i’s degree. if(_min[id * 2 + 1] < val){
memset(cntmin, 0, sizeof cntmin);
st[id * 2 + 1] += cntmin[id * 2 + 1] * (val - _min[id * 2 + 1]);
memset(cntmax, 0, sizeof cntmax);
_min[id * 2 + 1] = val;
A Markov chain is ergodic if the asymptotic distribution is }
if(mid + 1 == r) _max[id * 2 + 1] = val;
void combine(int id){
independent of the initial distribution. A finite Markov chain is else{
_max[id] = max(_max[id * 2], _max[id * 2 + 1]);
if(_max[id * 2 + 1] < val) _max[id * 2 + 1] = val;
ergodic iff it is irreducible and aperiodic (i.e., the gcd of cycle int tmp = max(_semax[id * 2], _semax[id * 2 + 1]);
else if(_semax[id * 2 + 1] < val) _semax[id * 2 + 1] = val;
if(_max[id * 2] > _max[id * 2 + 1]){
}
lengths is 1). limk→∞ Pk = 1π. _semax[id] = max(tmp, _max[id * 2 + 1]);
}
cntmax[id] = cntmax[id * 2];
}
A Markov chain is an A-chain if the states can be partitioned }
void build(int id, int l, int r){
else if(_max[id * 2] < _max[id * 2 + 1]){
into two sets A and G, such that all states in A are absorbing if(l == r){
_semax[id] = max(tmp, _max[id * 2]);
_max[id] = _min[id] = st[id] = a[l];
cntmax[id] = cntmax[id * 2 + 1];
(pii = 1), and all states in G leads to an absorbing state in A. }
_semax[id] = -oo;
_semin[id] = oo;
The probability for absorption in state i ∈ A, when the initial else{
cntmax[id] = cntmin[id] = 1;
P _semax[id] = tmp;
state is j, is aij = pij + k∈G aik pkj . The expected return;
P time until cntmax[id] = cntmax[id * 2] + cntmax[id * 2 + 1];
}
absorption, when the initial state is i, is ti = 1 + k∈G pki tk . }
int mid = (l + r) / 2;
_min[id] = min(_min[id * 2], _min[id * 2 + 1]);
build(id * 2, l, mid);
tmp = min(_semin[id * 2], _semin[id * 2 + 1]);
build(id * 2 + 1, mid + 1, r);
if(_min[id * 2] < _min[id * 2 + 1]){
combine(id);
_semin[id] = min(tmp, _min[id * 2 + 1]);
}
Data structures (3) }
cntmin[id] = cntmin[id * 2];
void upd_chmax(int id, int l, int r, int u, int v, int val){
if(l > v || r < u || _min[id] >= val) return;
else if(_min[id * 2] > _min[id * 2 + 1]){
OrderStatisticTree.h _semin[id] = min(tmp, _min[id * 2]);
if(l >= u && r <= v && _semin[id] > val){
Description: A set (not multiset!) with support for finding the n’th ele- st[id] += cntmin[id] * (val - _min[id]);
cntmin[id] = cntmin[id * 2 + 1];
ment, and finding the index of an element. To get a map, change null type. _min[id] = val;
}
if(l == r) _max[id] = val;
Time: O (log N ) else{
782797, 16 lines else{
_semin[id] = tmp;
#include <bits/extc++.h> if(_max[id] < val) _max[id] = val;
cntmin[id] = cntmin[id * 2] + cntmin[id * 2 + 1];
else if(_semax[id] < val) _semax[id] = val;
using namespace __gnu_pbds; }
}
st[id] = st[id * 2] + st[id * 2 + 1];
return;
template<class T> }
}
KTH LineContainer Treap SegmentTree SegmentTreeLazy CountingLargePrime DynamicWaveletTree 4
down(id, l, r);
if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); CountingLargePrime.h
int mid = (l + r) / 2;
while ((y = x) != begin() && (--x)->p >= y->p) Description: Count the number of prime numbers up to N
upd_chmax(id * 2, l, mid, u, v, val); isect(x, erase(y)); Time: For a single run in O (sqrt(N )). e62fac, 22 lines
upd_chmax(id * 2 + 1, mid + 1, r, u, v, val); }
combine(id); ll query(ll x) {
} assert(!empty()); ll piSieve(const ll n){
void upd_chmin(int id, int l, int r, int u, int v, int val){ if (n <= 1) return 0LL;
auto l = *lower_bound(x); if (n == 2) return 1LL;
if(l > v || r < u || _max[id] <= val) return; return l.k * x + l.m;
if(l >= u && r <= v && _semax[id] < val){ const int lim = int(sqrt(n));
st[id] -= cntmax[id] * (_max[id] - val);
} int vsz = (lim + 1) >> 1;
_max[id] = val; }; vector<int> smalls(vsz);
if(l == r) _min[id] = val; for (int i = 0; i < vsz ; ++i) smalls[i] = i;
else{ vector <int> roughs(vsz);
if(_min[id] > val) _min[id] = val; Treap.h for(int cx = 0; cx < vsz; ++cx) roughs[cx]= (cx << 1 | 1);
else if(_semin[id] > val) _semin[id] = val; vector <ll> larges(vsz);
Description: A short self-balancing tree. It acts as a sequential container
} for (int cx = 0; cx < vsz;++cx) larges[cx] = (n / (cx << 1 | 1) - 1) >> 1;
with log-time splits/joins, and is easy to augment with additional data. vector <bool> skips(lim+1);
return;
}
Time: O (log N ) 9556fc, 55 lines int pCnt=0;
down(id, l, r); for(int p=3;p<=lim;p+=2){
struct Node { if (skips[p]) continue;
int mid = (l + r) / 2;
upd_chmin(id * 2, l, mid, u, v, val);
Node *l = 0, *r = 0; int p2 = p * p;
upd_chmin(id * 2 + 1, mid + 1, r, u, v, val); int val, y, c = 1; if(1LL * p2 * p2 > n) break;
combine(id); Node(int val) : val(val), y(rand()) {} skips[p] = true;
} void recalc(); for(int cx = p2; cx <= lim; cx += (p << 1))
void upd_sum(int id, int l, int r, int u, int v, int val){ }; skips[cx] = true;
if(l > v || r < u) return; int ns = 0;
if(l >= u && r <= v){ for(int cx = 0; cx < vsz; ++cx){
int cnt(Node* n) { return n ? n->c : 0; } int cur = roughs[cx];
st[id] += (r - l + 1) * val;
lazy[id] += val;
void Node::recalc() { c = cnt(l) + cnt(r) + 1; } if(skips[cur]) continue;
_max[id] += val; ll d = 1LL * cur * p;
_min[id] += val; template<class F> void each(Node* n, F f) { larges[ns]=larges[cx]-(d<=lim?larges[smalls[d>>1]-pCnt]
if(_semax[id] != -oo) _semax[id] += val; if (n) { each(n->l, f); f(n->val); each(n->r, f); } :smalls[(ll((double(n)/d)-1))>>1])+pCnt;
if(_semin[id] != oo) _semin[id] += val; } roughs[ns++]=cur;
return; }
} vsz=ns;
pair<Node*, Node*> split(Node* n, int k) { for(int cx=(lim-1)>>1,cy=((lim/p)-1)|1;cy>=p;cy-=2){
int mid = (l + r) / 2;
down(id, l, r);
if (!n) return {}; int cur=smalls[cy>>1]-pCnt;
upd_sum(id * 2, l, mid, u, v, val); if (cnt(n->l) >= k) { // ”n−>val >= k” for lower bound(k) for(int cz=(cy*p)>>1;cz<=cx;--cx)
upd_sum(id * 2 + 1, mid + 1, r, u, v, val); auto pa = split(n->l, k); smalls[cx]-=cur;
combine(id); n->l = pa.second; }
} n->recalc(); ++pCnt;
int get(int id, int l, int r, int u, int v){ }
return {pa.first, n}; larges[0]+=1LL*(vsz+((pCnt-1)<<1))*(vsz-1)>>1;
if(l > v || r < u) return 0; } else {
if(l >= u && r <= v) return st[id]; for(int cx=1;cx<vsz;++cx) larges[0]-=larges[cx];
int mid = (l + r) / 2;
auto pa = split(n->r, k - cnt(n->l) - 1); // and j u s t ”k” for(int cx=1;cx<vsz;++cx){
down(id, l, r); n->r = pa.first; int q=roughs[cx];
return get(id * 2, l, mid, u, v) + get(id * 2 + 1, mid + 1, r, u, v); n->recalc(); ll m=n/q;
} return {n, pa.second}; int e=smalls[((m/q)-1)>>1]-pCnt;
}; } if(e<cx+1) break;
ll t=0;
} for(int cy=cx+1;cy<=e;++cy)
LineContainer.h t+=smalls[ll((double(m)/roughs[cy])-1)>>1];
Description: Container where you can add lines of the form kx+m, and Node* merge(Node* l, Node* r) { larges[0]+=t-1LL*(e-cx)*(pCnt+cx-1);
query maximum values at points x. Useful for dynamic programming (“con- if (!l) return r; }
vex hull trick”). if (!r) return l; return larges[0]+1;
Time: O (log N ) if (l->y > r->y) { }
8ec1c7, 30 lines
l->r = merge(l->r, r);
struct Line {
mutable ll k, m, p;
l->recalc(); DynamicWaveletTree.h
bool operator<(const Line& o) const { return k < o.k; }
return l; Description: Given an array of n elements with q queries l, r, k. For each query print
bool operator<(ll x) const { return p < x; }
} else { the kth values if the subsequence [l, r] is sorted increasingly and the sum from the 1st to
};
r->l = merge(l, r->l); kth numbers. Calculate the position of k in the subsequence [l, r]
r->recalc();
Time: O (n log amax) 08bf48, 13 lines
return r;
struct LineContainer : multiset<Line, less<>> {
} struct WaveletTree{
// ( for doubles , use i nf = 1/.0 , div (a , b) = a/b) struct TNode{
}
static const ll inf = LLONG_MAX; int l, r;
ll div(ll a, ll b) { // floored division Node* ins(Node* t, Node* n, int pos) {
int lp, rp;
return a / b - ((a ^ b) < 0 && a % b); } auto pa = split(t, pos); TNode(){
bool isect(iterator x, iterator y) { return merge(merge(pa.first, n), pa.second); l = r = lp = rp = 0;
if (y == end()) return x->p = inf, 0; } }
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; // Example application : move the range [ l , r ) to index k TNode(int _l, int _r){
void move(Node*& t, int l, int r, int k) { l = _l;
else x->p = div(y->m - x->m, x->k - y->k); r = _r;
return x->p >= y->p; Node *a, *b, *c;
}
} tie(a,b) = split(t, l); tie(b,c) = split(b, r - l); };
void add(ll k, ll m) { if (k <= l) t = merge(ins(a, b, k), c); vector <vector <int>> val;
auto z = insert({k, m, 0}), y = z++, x = y; else t = merge(a, ins(c, b, k - r)); vector <vector <ll>> sum;
while (isect(y, z)) z = erase(z); } vector <int> b;
KTH Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence 5
vector <TNode> wt;
return res;
int wt_sz;
} PolyInterpolate.h
WaveletTree(){ Description: Given n points (x[i], y[i]), computes an n-1-degree polynomial
};
wt_sz = 1;
} p that passes through them: p(x) = a[0] ∗ x0 + ... + a[n − 1] ∗ xn−1 . For
void Assign(int _n = 0){ numerical precision, pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1.
Time: O n2

val.resize(_n * 4); 08bf48, 13 lines
sum.resize(_n * 4);
wt.resize(_n * 4); typedef vector<double> vd;
} vd interpolate(vd x, vd y, int n) {
template <class T> void build(int id, T i, T j, int l, int r){ vd res(n), temp(n);
wt[id].l = l; rep(k,0,n-1) rep(i,k+1,n)
wt[id].r = r; y[i] = (y[i] - y[k]) / (x[i] - x[k]);
if (l == r){
double last = 0; temp[0] = 1;
return;
} rep(k,0,n) rep(i,0,n) {
val[id].pb(0); res[i] += y[k] * temp[i];
sum[id].pb(0); swap(last, temp[i]);
int mid = (l + r - (l + r < 0)) / 2; temp[i] -= last * x[k];
int maxx = l;
int minn = r; Numerical (4) }
return res;
for (auto it = i; it != j; ++it){
}
val[id].pb(val[id].back() + (*it <= mid));
sum[id].pb(sum[id].back() + *it * (*it <= mid));
4.1 Polynomials and recurrences
if (*it <= mid) maxx = max(maxx, *it); BerlekampMassey.h
else minn = min(minn, *it); Polynomial.h Description: Recovers any n-order linear recurrence relation from the first
} c9b7b0, 17 lines
2n terms of the recurrence. Useful for guessing linear recurrences after brute-
auto p = stable_partition(i, j,[=](const auto &w){ struct Poly {
return w <= mid;
forcing the first terms. Should work on any field, but numerical stability for
vector<double> a; floats is not guaranteed. Output will have size ≤ n.
}); double operator()(double x) const {
wt[id].lp = ++wt_sz; Usage: berlekampMassey({0, 1, 1, 3, 5, 11}) // {1, 2}
wt[id].rp = ++wt_sz; double val = 0; Time: O N 2

build(wt[id].lp, i, p, l, maxx); for (int i = sz(a); i--;) (val *= x) += a[i]; "../number-theory/ModPow.h" 96548b, 20 lines
build(wt[id].rp, p, j, minn, r); return val;
} } vector<ll> berlekampMassey(vector<ll> s) {
ll pos(int k, int i, int j){ void diff() { int n = sz(s), L = 0, m = 0;
--i; rep(i,1,sz(a)) a[i-1] = i*a[i]; vector<ll> C(n), B(n), T;
ll cnt = 0; C[0] = B[0] = 1;
a.pop_back();
int id = 1;
int l = wt[id].l, r = wt[id].r; }
void divroot(double x0) { ll b = 1;
while (l < r){ rep(i,0,n) { ++m;
int mid = (l + r - (l + r < 0)) / 2; double b = a.back(), c; a.back() = 0;
if (k <= mid){ for(int i=sz(a)-1; i--;) c = a[i], a[i] = a[i+1]*x0+b, b=c; ll d = s[i] % mod;
i = val[id][i]; a.pop_back(); rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
j = val[id][j]; } if (!d) continue;
id = wt[id].lp; T = C; ll coef = d * modpow(b, mod-2) % mod;
};
} rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
else{ if (2 * L > i) continue;
cnt += val[id][j] - val[id][i]; PolyRoots.h L = i + 1 - L; B = T; b = d; m = 0;
i -= val[id][i]; Description: Finds the real roots to a polynomial.
j -= val[id][j];
}
id = wt[id].rp;
Usage: polyRoots({{2,-3,1}},-1e9,1e9) // solve xˆ2-3x+2 = 0
Time: O n2 log(1/)

} C.resize(L + 1); C.erase(C.begin());
l = wt[id].l, r = wt[id].r; "Polynomial.h" b00bfe, 23 lines for (ll& x : C) x = (mod - x) % mod;
} vector<double> polyRoots(Poly p, double xmin, double xmax) { return C;
if (k >= l) cnt += j - i; if (sz(p.a) == 2) { return {-p.a[0]/p.a[1]}; } }
return cnt;
}
vector<double> ret;
ll get(int k, int i, int j){ Poly der = p; LinearRecurrence.h
if (k == 0) return 0; der.diff(); Description: Generates the k’th term of an n-order linear recurrence
--i; auto dr = polyRoots(der, xmin, xmax); P
S[i] = j S[i − j − 1]tr[j], given S[0 . . . ≥ n − 1] and tr[0 . . . n − 1]. Faster
ll res = 0; dr.push_back(xmin-1);
int id = 1; than matrix multiplication. Useful together with Berlekamp–Massey.
dr.push_back(xmax+1); Usage: linearRec({0, 1}, {1, 1}, k) // k’th Fibonacci number
int l = wt[id].l, r = wt[id].r; sort(all(dr)); Time: O n2 log k

while (l < r){ f4e444, 26 lines
if (k <= val[id][j] - val[id][i]){
rep(i,0,sz(dr)-1) {
i = val[id][i]; double l = dr[i], h = dr[i+1]; typedef vector<ll> Poly;
j = val[id][j]; bool sign = p(l) > 0; ll linearRec(Poly S, Poly tr, ll k) {
id = wt[id].lp; if (sign ^ (p(h) > 0)) { int n = sz(tr);
} rep(it,0,60) { // while (h − l > 1e−8)
else{ double m = (l + h) / 2, f = p(m); auto combine = [&](Poly a, Poly b) {
res += sum[id][j] - sum[id][i]; if ((f <= 0) ^ sign) l = m; Poly res(n * 2 + 1);
k -= val[id][j] - val[id][i];
i -= val[id][i];
else h = m; rep(i,0,n+1) rep(j,0,n+1)
j -= val[id][j]; } res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
id = wt[id].rp; ret.push_back((l + h) / 2); for (int i = 2 * n; i > n; --i) rep(j,0,n)
} } res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
l = wt[id].l, r = wt[id].r; } res.resize(n + 1);
}
return ret; return res;
res += k * l;
} };
KTH GoldenSectionSearch HillClimbing Integrate IntegrateAdaptive Simplex Determinant IntDeterminant 6
rep(i,1,n*2) rep(j,0,n+2) if (j != s) D[r][j] *= inv;
Poly pol(n + 1), e(pol); v += f(a + i*h) * (i&1 ? 4 : 2); rep(i,0,m+2) if (i != r) D[i][s] *= -inv;
pol[0] = e[1] = 1; return v * h / 3; D[r][s] = inv;
} swap(B[r], N[s]);
for (++k; k; k /= 2) { }
if (k % 2) pol = combine(pol, e);
e = combine(e, e); IntegrateAdaptive.h bool simplex(int phase) {
} Description: Fast integration using an adaptive Simpson’s rule. int x = m + phase - 1;
Usage: double sphereVolume = quad(-1, 1, [](double x) { for (;;) {
ll res = 0; return quad(-1, 1, [&](double y) { int s = -1;
rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod; return quad(-1, 1, [&](double z) { rep(j,0,n+1) if (N[j] != -phase) ltj(D[x]);
return res; return x*x + y*y + z*z < 1; });});}); 92dd79, 15 lines if (D[x][s] >= -eps) return true;
} typedef double d; int r = -1;
#define S(a,b) (f(a) + 4*f((a+b) / 2) + f(b)) * (b-a) / 6 rep(i,0,m) {
if (D[i][s] <= eps) continue;
4.2 Optimization template <class F> if (r == -1 || MP(D[i][n+1] / D[i][s], B[i])
< MP(D[r][n+1] / D[r][s], B[r])) r = i;
d rec(F& f, d a, d b, d eps, d S) {
d c = (a + b) / 2; }
GoldenSectionSearch.h d S1 = S(a, c), S2 = S(c, b), T = S1 + S2; if (r == -1) return false;
Description: Finds the argument minimizing the function f in the inter- if (abs(T - S) <= 15 * eps || b - a < 1e-10) pivot(r, s);
val [a, b] assuming f is unimodal on the interval, i.e. has only one local return T + (T - S) / 15; }
minimum. The maximum error in the result is eps. Works equally well for return rec(f, a, c, eps / 2, S1) + rec(f, c, b, eps / 2, S2); }
maximization with a small change in the code. See TernarySearch.h in the }
Various chapter for a discrete version. template<class F> T solve(vd &x) {
Usage: double func(double x) { return 4+x+.3*x*x; } d quad(d a, d b, F f, d eps = 1e-8) { int r = 0;
double xmin = gss(-1000,1000,func); return rec(f, a, b, eps, S(a, b)); rep(i,1,m) if (D[i][n+1] < D[r][n+1]) r = i;
Time: O (log((b − a)/)) 31d45b, 14 lines } if (D[r][n+1] < -eps) {
double gss(double a, double b, double (*f)(double)) { pivot(r, n);
double r = (sqrt(5)-1)/2, eps = 1e-7; if (!simplex(2) || D[m+1][n+1] < -eps) return -inf;
Simplex.h rep(i,0,m) if (B[i] == -1) {
double x1 = b - r*(b-a), x2 = a + r*(b-a);
Description: Solves a general linear maximization problem: maximize cT x int s = 0;
double f1 = f(x1), f2 = f(x2);
subject to Ax ≤ b, x ≥ 0. Returns -inf if there is no solution, inf if there rep(j,1,n+1) ltj(D[i]);
while (b-a > eps)
are arbitrarily good solutions, or the maximum value of cT x otherwise. The pivot(i, s);
if (f1 < f2) { //change to > to find maximum
input vector is set to an optimal x (or in the unbounded case, an arbitrary }
b = x2; x2 = x1; f2 = f1;
solution fulfilling the constraints). Numerical stability is not guaranteed. For }
x1 = b - r*(b-a); f1 = f(x1);
better performance, define variables such that x = 0 is viable. bool ok = simplex(1); x = vd(n);
} else {
Usage: vvd A = {{1,-1}, {-1,1}, {-1,-2}}; rep(i,0,m) if (B[i] < n) x[B[i]] = D[i][n+1];
a = x1; x1 = x2; f1 = f2;
vd b = {1,1,-4}, c = {-1,-1}, x; return ok ? D[m][n+1] : inf;
x2 = a + r*(b-a); f2 = f(x2);
T val = LPSolver(A, b, c).solve(x); }
}
Time: O (N M ∗ #pivots), where a pivot may be e.g. an edge relaxation. };
return a;
O (2n ) in the general case.
} aa8530, 68 lines

typedef double T; // long double , Rational , double + mod<P>...


HillClimbing.h typedef vector<T> vd; 4.3 Matrices
Description: Poor man’s optimization for unimodal functions.8eeeaf, typedef vector<vd> vvd;
14 lines
Determinant.h
typedef array<double, 2> P; const T eps = 1e-8, inf = 1/.0; Description: Calculates determinant of a matrix. Destroys the matrix.
#define MP make_pair Time: O N 3 bd5cec, 15 lines
template<class F> pair<double, P> hillClimb(P start, F f) { #define ltj(X) if(s == -1 || MP(X[j],N[j]) < MP(X[s],N[s])) s=j
pair<double, P> cur(f(start), start); double det(vector<vector<double>>& a) {
for (double jmp = 1e9; jmp > 1e-20; jmp /= 2) { struct LPSolver { int n = sz(a); double res = 1;
rep(j,0,100) rep(dx,-1,2) rep(dy,-1,2) { int m, n; rep(i,0,n) {
P p = cur.second; vi N, B; int b = i;
p[0] += dx*jmp; vvd D; rep(j,i+1,n) if (fabs(a[j][i]) > fabs(a[b][i])) b = j;
p[1] += dy*jmp; if (i != b) swap(a[i], a[b]), res *= -1;
cur = min(cur, make_pair(f(p), p)); LPSolver(const vvd& A, const vd& b, const vd& c) : res *= a[i][i];
} m(sz(b)), n(sz(c)), N(n+1), B(m), D(m+2, vd(n+2)) { if (res == 0) return 0;
} rep(i,0,m) rep(j,0,n) D[i][j] = A[i][j]; rep(j,i+1,n) {
return cur; rep(i,0,m) { B[i] = n+i; D[i][n] = -1; D[i][n+1] = b[i];} double v = a[j][i] / a[i][i];
} rep(j,0,n) { N[j] = j; D[m][j] = -c[j]; } if (v != 0) rep(k,i+1,n) a[j][k] -= v * a[i][k];
N[n] = -1; D[m+1][n] = 1; }
} }
Integrate.h return res;
Description: Simple integration of a function over an interval using Simp- }
son’s rule. The error should be proportional to h4 , although in practice you void pivot(int r, int s) {
will want to verify that the result is stable to desired precision when epsilon T *a = D[r].data(), inv = 1 / a[s];
changes. rep(i,0,m+2) if (i != r && abs(D[i][s]) > eps) { IntDeterminant.h
4756fc, 7 lines T *b = D[i].data(), inv2 = b[s] * inv; Description: Calculates determinant using modular arithmetics. Modulos
template<class F> rep(j,0,n+2) b[j] -= a[j] * inv2; can also be removed to get a pure-integer version.
Time: O N 3

double quad(double a, double b, F f, const int n = 1000) { b[s] = a[s] * inv2;
3313dc, 18 lines
double h = (b - a) / 2 / n, v = f(a) + f(b); }
KTH SolveLinear SolveLinear2 SolveLinearBinary MatrixInverse Tridiagonal 7
const ll mod = 12345; x.assign(m, undefined); rep(j,i+1,n) {
ll det(vector<vector<ll>>& a) { rep(i,0,rank) { double f = A[j][i] / v;
int n = sz(a); ll ans = 1; rep(j,rank,m) if (fabs(A[i][j]) > eps) goto fail; A[j][i] = 0;
rep(i,0,n) { x[col[i]] = b[i] / A[i][i]; rep(k,i+1,n) A[j][k] -= f*A[i][k];
rep(j,i+1,n) { fail:; } rep(k,0,n) tmp[j][k] -= f*tmp[i][k];
while (a[j][i] != 0) { // gcd step }
ll t = a[i][i] / a[j][i]; rep(j,i+1,n) A[i][j] /= v;
if (t) rep(k,i,n) SolveLinearBinary.h rep(j,0,n) tmp[i][j] /= v;
a[i][k] = (a[i][k] - a[j][k] * t) % mod; Description: Solves Ax = b over F2 . If there are multiple solutions, one is A[i][i] = 1;
swap(a[i], a[j]); returned arbitrarily. Returns rank, or -1 if no solutions. Destroys A and b. }
Time: O n2 m

ans *= -1; fa2d7a, 34 lines
} typedef bitset<1000> bs; for (int i = n-1; i > 0; --i) rep(j,0,i) {
} double v = A[j][i];
ans = ans * a[i][i] % mod; int solveLinear(vector<bs>& A, vi& b, bs& x, int m) { rep(k,0,n) tmp[j][k] -= v*tmp[i][k];
if (!ans) return 0; int n = sz(A), rank = 0, br; }
} assert(m <= sz(x));
return (ans + mod) % mod; vi col(m); iota(all(col), 0); rep(i,0,n) rep(j,0,n) A[col[i]][col[j]] = tmp[i][j];
} rep(i,0,n) { return n;
for (br=i; br<n; ++br) if (A[br].any()) break; }
SolveLinear.h if (br == n) {
Description: Solves A ∗ x = b. If there are multiple solutions, an arbitrary rep(j,i,n) if(b[j]) return -1; Tridiagonal.h
one is returned. Returns rank, or -1 if no solutions. Data in A and b is lost. break; Description: x = tridiagonal(d, p, q, b) solves the equation system
Time: O n2 m 44c9ab, 38 lines
} 
b0
 
d0 p0 0 0 ··· 0

x0

int bc = (int)A[br]._Find_next(i-1);
typedef vector<double> vd; b 1  0q d 1 p 1 0 · · · 0   x1
swap(A[i], A[br]);   
const double eps = 1e-12;
 b
2
  0 q1 d2 p2 ··· 0  x
2

swap(b[i], b[br]); 
 b
  
 x

= . . . .
  
swap(col[i], col[bc]);  3
 . . . .. . .. . .. .
 3
.  . . . .
   
int solveLinear(vector<vd>& A, vd& b, vd& x) { rep(j,0,n) if (A[j][i] != A[j][bc]) { 
.
 
.

int n = sz(A), m = sz(x), rank = 0, br, bc; A[j].flip(i); A[j].flip(bc);
 .   0 0 ··· qn−3 dn−2 pn−2   . 
if (n) assert(sz(A[0]) == m); } bn−1 0 0 ··· 0 qn−2 dn−1 xn−1
vi col(m); iota(all(col), 0); rep(j,i+1,n) if (A[j][i]) { This is useful for solving problems on the type
b[j] ^= b[i];
rep(i,0,n) { A[j] ^= A[i]; ai = bi ai−1 + ci ai+1 + di , 1 ≤ i ≤ n,
double v, bv = 0; } where a0 , an+1 , bi , ci and di are known. a can then be obtained from
rep(r,i,n) rep(c,i,m) rank++;
if ((v = fabs(A[r][c])) > bv) {ai } = tridiagonal({1, −1, −1, ..., −1, 1}, {0, c1 , c2 , . . . , cn },
}
br = r, bc = c, bv = v; {b1 , b2 , . . . , bn , 0}, {a0 , d1 , d2 , . . . , dn , an+1 }).
if (bv <= eps) { x = bs(); Fails if the solution is not unique.
rep(j,i,n) if (fabs(b[j]) > eps) return -1; for (int i = rank; i--;) { If |di | > |pi | + |qi−1 | for all i, or |di | > |pi−1 | + |qi |, or the matrix is positive
break; if (!b[i]) continue; definite, the algorithm is numerically stable and neither tr nor the check for
} x[col[i]] = 1; diag[i] == 0 is needed.
swap(A[i], A[br]); rep(j,0,i) b[j] ^= A[j][i]; Time: O (N )
swap(b[i], b[br]); 8f9fa8, 26 lines
}
swap(col[i], col[bc]); return rank; // ( multiple solutions i f rank < m) typedef double T;
rep(j,0,n) swap(A[j][i], A[j][bc]); } vector<T> tridiagonal(vector<T> diag, const vector<T>& super,
bv = 1/A[i][i]; const vector<T>& sub, vector<T> b) {
rep(j,i+1,n) { int n = sz(b); vi tr(n);
double fac = A[j][i] * bv; MatrixInverse.h rep(i,0,n-1) {
b[j] -= fac * b[i]; Description: Invert matrix A. Returns rank; result is stored in A unless if (abs(diag[i]) < 1e-9 * abs(super[i])) { // diag [ i ] == 0
rep(k,i+1,m) A[j][k] -= fac*A[i][k]; singular (rank < n). Can easily be extended to prime moduli; for prime b[i+1] -= b[i] * diag[i+1] / super[i];
} powers, repeatedly set A−1 = A−1 (2I − AA−1 ) (mod pk ) where A−1 starts if (i+2 < n) b[i+2] -= b[i] * sub[i+1] / super[i];
rank++; as the inverseof A mod p, and k is doubled in each step. diag[i+1] = sub[i]; tr[++i] = 1;
} Time: O n3 ebfff6, 35 lines } else {
diag[i+1] -= super[i]*sub[i]/diag[i];
x.assign(m, 0); int matInv(vector<vector<double>>& A) {
b[i+1] -= b[i]*sub[i]/diag[i];
for (int i = rank; i--;) { int n = sz(A); vi col(n);
}
b[i] /= A[i][i]; vector<vector<double>> tmp(n, vector<double>(n));
}
x[col[i]] = b[i]; rep(i,0,n) tmp[i][i] = 1, col[i] = i;
for (int i = n; i--;) {
rep(j,0,i) b[j] -= A[j][i] * b[i]; if (tr[i]) {
} rep(i,0,n) {
swap(b[i], b[i-1]);
return rank; // ( multiple solutions i f rank < m) int r = i, c = i;
diag[i-1] = diag[i];
} rep(j,i,n) rep(k,i,n)
b[i] /= super[i-1];
if (fabs(A[j][k]) > fabs(A[r][c]))
} else {
r = j, c = k;
SolveLinear2.h if (fabs(A[r][c]) < 1e-12) return i;
b[i] /= diag[i];
Description: To get all uniquely determined values of x back from Solve- if (i) b[i-1] -= b[i]*super[i-1];
A[i].swap(A[r]); tmp[i].swap(tmp[r]);
Linear, make the following changes: }
rep(j,0,n)
"SolveLinear.h" 08e495, 7 lines }
swap(A[j][i], A[j][c]), swap(tmp[j][i], tmp[j][c]);
return b;
rep(j,0,n) if (j != i) // instead of rep( j , i +1,n) swap(col[i], col[c]);
}
// . . . then at the end : double v = A[i][i];
KTH FastFourierTransform FastFourierTransformMod NumberTheoreticTransform FastSubsetTransform ModularArithmetic ModInverse ModPow ModLog 8
4.4 Fourier transforms ll av = ll(real(outl[i])+.5), cv = ll(imag(outs[i])+.5); if (inv) for (int& x : a) x /= sz(a); // XOR only
ll bv = ll(imag(outl[i])+.5) + ll(real(outs[i])+.5); }
FastFourierTransform.h res[i] = ((av % M * cut + bv) % M * cut + cv) % M; vi conv(vi a, vi b) {
Description: fft(a) computes fˆ(k) =
P } FST(a, 0); FST(b, 0);
x a[x] exp(2πi · kx/N ) for all k.
N mustPbe a power of 2. Useful for convolution: conv(a, b) = c, where return res; rep(i,0,sz(a)) a[i] *= b[i];
c[x] = a[i]b[x − i]. For convolution of complex numbers or more than two } FST(a, 1); return a;
vectors: FFT, multiply pointwise, divide by n, reverse(start+1, end), FFT }
back. Rounding is safe if ( a2i + b2i ) log2 N < 9 · 1014 (in practice 1016 ; NumberTheoreticTransform.h
P P
higher for random inputs). Otherwise, use NTT/FFTMod. Description: ntt(a) computes fˆ(k) = xk
P
x a[x]g for all k, where g =
Time: O (N log N ) with N = |A| + |B| (∼1s for N = 222 ) 00ced6, 35 lines root(mod−1)/N . N must be a power of 2. Useful for convolution modulo spe- Number theory (5)
using cd = complex<double>; cific nice primes of the form 2a b + 1, where the convolution result has size
const double PI = acos(-1);
void fft(vector<cd> & a, bool invert) {
at mostP 2a . For arbitrary modulo, see FFTMod. conv(a, b) = c, where 5.1 Modular arithmetic
c[x] = a[i]b[x − i]. For manual convolution: NTT the inputs, multiply
int n = a.size(); pointwise, divide by n, reverse(start+1, end), NTT back. Inputs must be in
for (int i = 1, j = 0; i < n; i++) {
[0, mod).
ModularArithmetic.h
int bit = n >> 1; Description: Operators for modular arithmetic. You need to set mod to
for (; j & bit; bit >>= 1) j ^= bit; Time: O (N log N )
some number first and then you can use the structure.
j ^= bit; "../number-theory/ModPow.h" ced03d, 33 lines
"euclid.h" 35bfea, 18 lines
if (i < j) swap(a[i], a[j]); const ll mod = (119 << 23) + 1, root = 62; // = 998244353
} const ll mod = 17; // change to something e l s e
// For p < 2^30 there i s also e . g . 5 << 25, 7 << 26, 479 << 21
for (int len = 2; len <= n; len <<= 1) { struct Mod {
double ang = 2 * PI / len * (invert ? -1 : 1); // and 483 << 21 (same root ) . The l a s t two are > 10^9.
ll x;
cd wlen(cos(ang), sin(ang)); typedef vector<ll> vl;
Mod(ll xx) : x(xx) {}
for (int i = 0; i < n; i += len) { void ntt(vl &a) {
Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
cd w(1); int n = sz(a), L = 31 - __builtin_clz(n);
for (int j = 0; j < len / 2; j++) { Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }
static vl rt(2, 1);
cd u = a[i+j], v = a[i+j+len/2] * w; Mod operator*(Mod b) { return Mod((x * b.x) % mod); }
for (static int k = 2, s = 2; k < n; k *= 2, s++) {
a[i+j] = u + v; Mod operator/(Mod b) { return *this * invert(b); }
rt.resize(n);
a[i+j+len/2] = u - v; Mod invert(Mod a) {
w *= wlen; ll z[] = {1, modpow(root, mod >> s)};
ll x, y, g = euclid(a.x, mod, x, y);
} rep(i,k,2*k) rt[i] = rt[i / 2] * z[i & 1] % mod;
assert(g == 1); return Mod((x + mod) % mod);
} }
}
} vi rev(n);
if (invert) for (cd & x : a) x /= n; Mod operator^(ll e) {
rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
} if (!e) return Mod(1);
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]);
vector<int> multiply(vector<int> const& a, vector<int> const& b) { Mod r = *this ^ (e / 2); r = r * r;
for (int k = 1; k < n; k *= 2)
vector<cd> fa(a.begin(), a.end()), fb(b.begin(), b.end()); return e&1 ? *this * r : r;
int n = 1; for (int i = 0; i < n; i += 2 * k) rep(j,0,k) {
}
while (n < a.size() + b.size()) n <<= 1; ll z = rt[j + k] * a[i + j + k] % mod, &ai = a[i + j];
};
fa.resize(n); a[i + j + k] = ai - z + (z > ai ? mod : 0);
fb.resize(n); ai += (ai + z >= mod ? z - mod : z);
fft(fa, false); fft(fb, false); } ModInverse.h
for (int i = 0; i < n; i++) } Description: Pre-computation of modular inverses. Assumes LIM ≤ mod
fa[i] *= fb[i]; and that mod is a prime.
vl conv(const vl &a, const vl &b) {
fft(fa, true); 6f684f, 3 lines
vector<int> result(n); if (a.empty() || b.empty()) return {};
int s = sz(a) + sz(b) - 1, B = 32 - __builtin_clz(s), n = 1 const ll mod = 1000000007, LIM = 200000;
for (int i = 0; i < n; i++) ll* inv = new ll[LIM] - 1; inv[1] = 1;
result[i] = round(fa[i].real()); << B;
return result; int inv = modpow(n, mod - 2); rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[mod % i] % mod;
} vl L(a), R(b), out(n);
L.resize(n), R.resize(n); ModPow.h b83e45, 8 lines
ntt(L), ntt(R);
FastFourierTransformMod.h rep(i,0,n) out[-i & (n - 1)] = (ll)L[i] * R[i] % mod * inv % const ll mod = 1000000007; // faster i f const
Description: Higher precision FFT, can be used for convolutions modulo mod;
arbitrary integers as long as N log2 N · mod < 8.6 · 1014 (in practice 1016 or ntt(out); ll modpow(ll b, ll e) {
higher). Inputs must b e in [0, mo d). return {out.begin(), out.begin() + s}; ll ans = 1;
Time: O (N log N ), where N = |A| + |B| (twice as slow as NTT or FFT) } for (; e; b = b * b % mod, e /= 2)
"FastFourierTransform.h" b82773, 22 lines if (e & 1) ans = ans * b % mod;
typedef vector<ll> vl; return ans;
template<int M> vl convMod(const vl &a, const vl &b) { FastSubsetTransform.h }
if (a.empty() || b.empty()) return {}; Description:
X Transform to a basis with fast convolutions of the form
vl res(sz(a) + sz(b) - 1); c[z] = a[x] · b[y], where ⊕ is one of AND, OR, XOR. The size ModLog.h
z=x⊕y
int B=32-__builtin_clz(sz(res)), n=1<<B, cut=int(sqrt(M)); of a must be a power of two. Description: Returns the smallest x > 0 s.t. ax = b (mod m), or −1 if no
vector<C> L(n), R(n), outs(n), outl(n); Time: O (N log N ) such x exists.
rep(i,0,sz(a)) L[i] = C((int)a[i] / cut, (int)a[i] % cut); 464cf3, 16 lines √ modLog(a,1,m)
 can be used to calculate the order of a.
Time: O m c040b8, 11 lines
rep(i,0,sz(b)) R[i] = C((int)b[i] / cut, (int)b[i] % cut); void FST(vi& a, bool inv) {
fft(L), fft(R); for (int n = sz(a), step = 1; step < n; step *= 2) { ll modLog(ll a, ll b, ll m) {
rep(i,0,n) { for (int i = 0; i < n; i += 2 * step) rep(j,i,i+step) { ll n = (ll) sqrt(m) + 1, e = 1, f = 1, j = 1;
int j = -i & (n - 1); int &u = a[j], &v = a[j + step]; tie(u, v) = unordered_map<ll, ll> A;
outl[j] = (L[i] + conj(L[j])) * R[i] / (2.0 * n); inv ? pii(v - u, u) : pii(v, u + v); // AND while (j <= n && (e = f = e * a % m) != b % m)
outs[j] = (L[i] - conj(L[j])) * R[i] / (2.0 * n) / 1i; inv ? pii(v, u - v) : pii(u + v, u); // OR A[e * b % m] = j++;
} pii(u + v, u - v); // XOR if (e == b % m) return j;
fft(outl), fft(outs); } if (__gcd(m, e) == __gcd(m, b))
rep(i,0,sz(res)) { } rep(i,2,n+2) if (A.count(e = e * f % m))
KTH ModSum ModMulLL ModSqrt FastEratosthenes MillerRabin Factor euclid CRT phiFunction 9
return n * i - A[e]; b = b * g % p; if (isPrime(n)) return {n};
return -1; } ull x = pollard(n);
} } auto l = factor(x), r = factor(n / x);
l.insert(l.end(), all(r));
ModSum.h return l;
Description: Sums of mod’ed
Pto−1arithmetic progressions. 5.2 Primality }
modsum(to, c, k, m) = i=0 (ki + c)%m. divsum is similar but for
floored division. FastEratosthenes.h 5.3 Divisibility
Time: log(m), with a large constant. 5c5bc5, 16 lines
Description: Prime sieve for generating all primes smaller than LIM.
Time: LIM=1e9 ≈ 1.5s 6b2912, 20 lines
typedef unsigned long long ull; euclid.h
ull sumsq(ull to) { return to / 2 * ((to-1) | 1); } const int LIM = 1e6; Description: Finds two integers x and y, such that ax + by = gcd(a, b). If
bitset<LIM> isPrime; you just need gcd, use the built in gcd instead. If a and b are coprime, then
ull divsum(ull to, ull c, ull k, ull m) { vi eratosthenes() { x is the inverse of a (mod b). 33ba8f, 5 lines
ull res = k / m * sumsq(to) + c / m * to; const int S = (int)round(sqrt(LIM)), R = LIM / 2;
k %= m; c %= m; vi pr = {2}, sieve(S+1); pr.reserve(int(LIM/log(LIM)*1.1)); ll euclid(ll a, ll b, ll &x, ll &y) {
if (!k) return res; vector<pii> cp; if (!b) return x = 1, y = 0, a;
ull to2 = (to * k + c) / m; for (int i = 3; i <= S; i += 2) if (!sieve[i]) { ll d = euclid(b, a % b, y, x);
return res + (to - 1) * to2 - divsum(to2, m-1 - c, m, k); cp.push_back({i, i * i / 2}); return y -= a/b * x, d;
} for (int j = i * i; j <= S; j += 2 * i) sieve[j] = 1; }
}
ll modsum(ull to, ll c, ll k, ll m) { for (int L = 1; L <= R; L += S) { CRT.h
c = ((c % m) + m) % m; array<bool, S> block{}; Description: Chinese Remainder Theorem.
k = ((k % m) + m) % m; for (auto &[p, idx] : cp) crt(a, m, b, n) computes x such that x ≡ a (mod m), x ≡ b (mod n). If
return to * c + k * sumsq(to) - m * divsum(to, c, k, m); for (int i=idx; i < S+L; idx = (i+=p)) block[i-L] = 1; |a| < m and |b| < n, x will obey 0 ≤ x < lcm(m, n). Assumes mn < 262 .
} rep(i,0,min(S, R - L)) Time: log(n)
if (!block[i]) pr.push_back((L + i) * 2 + 1); "euclid.h" 04d93a, 7 lines

ModMulLL.h } ll crt(ll a, ll m, ll b, ll n) {
Description: Calculate a·b mod c (or ab mod c) for 0 ≤ a, b ≤ c ≤ 7.2·1018 . for (int i : pr) isPrime[i] = 1; if (n > m) swap(a, b), swap(m, n);
Time: O (1) for modmul, O (log b) for modpow return pr; ll x, y, g = euclid(m, n, x, y);
bbbd8f, 11 lines } assert((a - b) % g == 0); // e l s e no solution
typedef unsigned long long ull; x = (b - a) % n * x % n / g * m + a;
ull modmul(ull a, ull b, ull M) { MillerRabin.h return x < 0 ? x + m*n/g : x;
ll ret = a * b - M * ull(1.L / M * a * b); Description: Deterministic Miller-Rabin primality test. Guaranteed to }
return ret + M * (ret < 0) - M * (ret >= (ll)M); work for numbers up to 7 · 1018 ; for larger numbers, use Python and ex-
} tend A randomly.
ull modpow(ull b, ull e, ull mod) { Time: 7 times the complexity of ab mod c. 5.3.1 Bézout’s identity
ull ans = 1; "ModMulLL.h" 60dcd1, 12 lines
for (; e; b = modmul(b, b, mod), e /= 2)
if (e & 1) ans = modmul(ans, b, mod);
bool isPrime(ull n) { For a 6=, b 6= 0, then d = gcd(a, b) is the smallest positive integer
if (n < 2 || n % 6 % 4 != 1) return (n | 1) == 3; for which there are integer solutions to
return ans;
ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
}
s = __builtin_ctzll(n-1), d = n >> s;
for (ull a : A) { // ^ count t r a i l i n g zeroes
ax + by = d
ModSqrt.h ull p = modpow(a%n, d, n), i = s;
Description: Tonelli-Shanks algorithm for modular square roots. Finds x while (p != 1 && p != n - 1 && a % n && i--) If (x, y) is one solution, then all solutions are given by
s.t. x2 = a (mod p) (−x gives the other solution). p = modmul(p, p, n);
Time: O log2 p worst case, O (log p) for most p
 
if (p != n-1 && i != s) return 0; kb ka
"ModPow.h" 19a793, 24 lines } x+ ,y − , k∈Z
ll sqrt(ll a, ll p) { return 1;
gcd(a, b) gcd(a, b)
a %= p; if (a < 0) a += p; }
if (a == 0) return 0; phiFunction.h
assert(modpow(a, (p-1)/2, p) == 1); // e l s e no solution Factor.h Description: Euler’s φ function is defined as φ(n) := # of positive integers
if (p % 4 == 3) return modpow(a, (p+1)/4, p); Description: Pollard-rho randomized factorization algorithm. Returns ≤ n that are coprime with n. φ(1) = 1, p prime ⇒ φ(pk ) = (p − 1)pk−1 ,
// a^(n+3)/8 or 2^(n+3)/8 ∗ 2^(n−1)/4 works i f p % 8 == 5
ll s = p - 1, n = 2;  ofa number, in arbitrary order (e.g. 2299 -> {11, 19, 11}).
prime factors k
m, n coprime ⇒ φ(mn) = φ(m)φ(n). If n = p1 1 p2 2 ...pk
k
r
r then φ(n) =
Time: O n1/4 , less for numbers with small factors. k1 −1 kr −1 Q
int r = 0, m; (p1 − 1)p1 ...(pr − 1)pr . φ(n) = n · p|n (1 − 1/p).
while (s % 2 == 0) "ModMulLL.h", "MillerRabin.h" a33cf6, 18 lines P P
d|n φ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nφ(n)/2, n > 1
++r, s /= 2; ull pollard(ull n) {
while (modpow(n, (p - 1) / 2, p) != p - 1) ++n; auto f = [n](ull x) { return modmul(x, x, n) + 1; }; Euler’s thm: a, n coprime ⇒ aφ(n) ≡ 1 (mod n).
ll x = modpow(a, (s + 1) / 2, p); ull x = 0, y = 0, t = 30, prd = 2, i = 1, q; Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 (mod p) ∀a. cf7d6d, 8 lines
ll b = modpow(a, s, p), g = modpow(n, s, p); while (t++ % 40 || __gcd(prd, n) == 1) {
const int LIM = 5000000;
for (;; r = m) { if (x == y) x = ++i, y = f(x);
int phi[LIM];
ll t = b; if ((q = modmul(prd, max(x,y) - min(x,y), n))) prd = q;
for (m = 0; m < r && t != 1; ++m) x = f(x), y = f(f(y));
void calculatePhi() {
t = t * t % p; }
rep(i,0,LIM) phi[i] = i&1 ? i : i/2;
if (m == 0) return x; return __gcd(prd, n);
for (int i = 3; i < LIM; i += 2) if(phi[i] == i)
ll gs = modpow(g, 1LL << (r - m - 1), p); }
for (int j = i; j < LIM; j += i) phi[j] -= phi[j] / i;
g = gs * gs % p; vector<ull> factor(ull n) {
}
x = x * gs % p; if (n == 1) return {};
KTH ContinuedFractions FracBinarySearch IntPerm 10
5.4 Fractions 5.5 Pythagorean Triples IntPerm.h
Description: Permutation -> integer conversion. (Not order preserving.)
The Pythagorean triples are uniquely generated by Integer -> permutation can use a lookup table.
Time: O (n) 044568, 6 lines

ContinuedFractions.h a = k · (m2 − n2 ), b = k · (2mn), c = k · (m2 + n2 ), int permToInt(vi& v) {


Description: Given N and a real number x ≥ 0, finds the closest rational int use = 0, i = 0, r = 0;
approximation p/q with p, q ≤ N . It will obey |p/q − x| ≤ 1/qN . with m > n > 0, k > 0, m⊥n, and either m or n even. for(int x:v) r = r * ++i + __builtin_popcount(use & -(1<<x)),
For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . (pk /qk alternates use |= 1 << x; // (note : minus, not ∼! )
return r;
between > x and < x.) If x is rational, y eventually becomes ∞; if x is the
root of a degree 2 polynomial the a’s eventually become cyclic.
5.6 Primes }
Time: O (log N ) dd6c5e, 21 lines p = 962592769 is such that 221 | p − 1, which may be useful. For
typedef double d; // for N ∼ 1e7 ; long double for N ∼ 1e9 hashing use 970592641 (31-bit number), 31443539979727 (45-bit), 6.1.2 Cycles
pair<ll, ll> approximate(d x, ll N) {
3006703054056749 (52-bit). There are 78498 primes less than
ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; d y = x; Let gS (n) be the number of n-permutations whose cycle lengths
for (;;) { 1 000 000.
ll lim = min(P ? (N-LP) / P : inf, Q ? (N-LQ) / Q : inf), all belong to the set S. Then
a = (ll)floor(y), b = min(a, lim), Primitive roots exist modulo any prime power pa , except for ∞
!
NP = b*P + LP, NQ = b*Q + LQ; p = 2, a > 2, and there are φ(φ(pa )) many. For p = 2, a > 2, the
X xn X xn
if (a > b) { gS (n) = exp
group Z× n! n
// I f b > a/2, we have a semi−convergent that gives us a 2a is instead isomorphic to Z2 × Z2a−2 . n=0 n∈S
// better approximation ; i f b = a/2, we ∗may∗ have one .
// Return {P, Q} here for a more canonical approximation .
return (abs(x - (d)NP / (d)NQ) < abs(x - (d)P / (d)Q)) ?
5.7 Estimates 6.1.3 Derangements
make_pair(NP, NQ) : make_pair(P, Q); P
} d|n d = O(n log log n). Permutations of a set such that none of the elements appear in
if (abs(y = 1/(y - (d)a)) > 3*N) { their original position.
return {NP, NQ}; The number of divisors of n is at most around 100 for n < 5e4,  
} 500 for n < 1e7, 2000 for n < 1e10, 200 000 for n < 1e19. n n!
LP = P; P = NP; D(n) = (n − 1)(D(n − 1) + D(n − 2)) = nD(n − 1) + (−1) =
LQ = Q; Q = NQ;
e
} 5.8 Mobius Function
}  6.1.4 Burnside’s lemma
0
 n is not square free
µ(n) = 1 n has even number of prime factors Given a group G of symmetries and a set X, the number of
elements of X up to symmetry equals

−1 n has odd number of prime factors

FracBinarySearch.h
Description: Given f and N , finds the smallest fraction p/q ∈ [0, 1] such Mobius Inversion: 1 X g
that f (p/q) is true, and p, q ≤ N . You may want to throw an exception from
|X |,
X X |G| g∈G
f if it finds an exact solution, in which case N can be removed. g(n) = f (d) ⇔ f (n) = µ(d)g(n/d)
Usage: fracBS([](Frac f) { return f.p>=3*f.q; }, 10); // {1,3}
Time: O (log(N )) d|n d|n where X g are the elements fixed by g (g.x = x).
27ab3e, 25 lines
struct Frac { ll p, q; }; Other useful formulas/forms: If f (n) counts “configurations” (of some sort) of length n, we can
template<class F>
P ignore rotational symmetry using G = Zn to get
d|n µ(d) = [n = 1] (very useful)
Frac fracBS(F f, ll N) { n−1
bool dir = 1, A = 1, B = 1; P P
g(n) = n|d f (d) ⇔ f (n) = n|d µ(d/n)g(d) 1X 1X
Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to search (0 , N] g(n) = f (gcd(n, k)) = f (k)φ(n/k).
if (f(lo)) return lo;
n n
P n P n k=0 k|n
assert(f(hi)); g(n) = 1≤m≤n f ( m ) ⇔ f (n) = 1≤m≤n µ(m)g( m )
while (A || B) {
ll adv = 0, step = 1; // move hi i f dir , e l s e lo 6.2 Partitions and subsets
for (int si = 0; step; (step *= 2) >>= si) {
adv += step; Combinatorial (6) 6.2.1 Partition function
Frac mid{lo.p * adv + hi.p, lo.q * adv + hi.q};
if (abs(mid.p) > N || mid.q > N || dir == !f(mid)) {
adv -= step; si = 2;
6.1 Permutations Number of ways of writing n as a sum of positive integers,
} disregarding the order of the summands.
} 6.1.1 Factorial X
hi.p += lo.p * adv;
n 123 4 5 6 7 8 9 10 p(0) = 1, p(n) = (−1)k+1 p(n − k(3k − 1)/2)
hi.q += lo.q * adv;
k∈Z\{0}
dir = !dir; n! 1 2 6 24 120 720 5040 40320 362880 3628800
swap(lo, hi); √
A = B; B = !!adv;
n 11 12 13 14 15 16 17 p(n) ∼ 0.145/n · exp(2.56 n)
} n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14
return dir ? hi : lo; n 0 1 2 3 4 5 6 7 8 9 20 50 100
n 20 25 30 40 50 100 150 171
}
n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL MAX p(n) 1 1 2 3 5 7 11 15 22 30 627 ∼2e5 ∼2e8
KTH multinomial BellmanFord FloydWarshall TopoSort 11
6.2.2 Lucas’ Theorem 6.3.4 Stirling numbers of the second kind nodes[s].dist = 0;
sort(all(eds), [](Ed a, Ed b) { return a.s() < b.s(); });
Let n, m be non-negative integers and p a prime. Write Partitions of n distinct elements into exactly k groups.
int lim = sz(nodes) / 2 + 2; // /3+100 with shuffled vertices
n= pk + ... +n1 p + n0 and m = mk pk + ... + m1 p + m0 . Then
 nkQ rep(i,0,lim) for (Ed ed : eds) {
n
≡ ki=0 m ni
(mod p). S(n, k) = S(n − 1, k − 1) + kS(n − 1, k) Node cur = nodes[ed.a], &dest = nodes[ed.b];
m i
if (abs(cur.dist) == inf) continue;
S(n, 1) = S(n, n) = 1 ll d = cur.dist + ed.w;
6.2.3 Binomials ! if (d < dest.dist) {
k dest.prev = ed.a;
multinomial.h 1 X k−j k
k + · · · + k  P
( ki )!
S(n, k) = (−1) jn dest.dist = (i < lim-1 ? d : -inf);
Description: Computes
1 n
= . k! j=0 j }
k1 , k2 , . . . , kn k1 !k2 !...kn ! a0a312, 6 lines }
ll multinomial(vi& v) { rep(i,0,lim) for (Ed e : eds) {
ll c = 1, m = v.empty() ? 1 : v[0]; 6.3.5 Bell numbers if (nodes[e.a].dist == -inf)
rep(i,1,sz(v)) rep(j,0,v[i]) nodes[e.b].dist = -inf;
c = c * ++m / (j+1); Total number of partitions of n distinct elements. B(n) = }
}
return c; 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, . . . . For p prime,
}
B(pm + n) ≡ mB(n) + B(n + 1) (mod p)
6.3 General purpose numbers
6.3.1 Bernoulli numbers 6.3.6 Labeled unrooted trees FloydWarshall.h
Description: Calculates all-pairs shortest path in a directed graph that
EGF of Bernoulli numbers is B(t) = t
(FFT-able). # on n vertices: nn−2 might have negative edge weights. Input is an distance matrix m, where
et −1
# on k existing trees of size ni : n1 n2 · · · nk nk−2 m[i][j] = inf if i and j are not adjacent. As output, m[i][j] is set to the
B[0, . . .] = [1, − 12 , 16 , 0, − 30
1 1
, 0, 42 , . . .] shortest distance between i and j, inf if no path, or -inf if the path goes
# with degrees di : (n − 2)!/((d1 − 1)! · · · (dn − 1)!) through a negative-weight cycle.
Sums of powers: Time: O N 3

531245, 12 lines
n
X 1 Xm 
m + 1 6.3.7 Catalan numbers const ll inf = 1LL << 62;
nm = Bk · (n + 1)m+1−k void floydWarshall(vector<vector<ll>>& m) {
i=1
m + 1 k=0 k
! ! ! int n = sz(m);
1 2n 2n 2n (2n)! rep(i,0,n) m[i][i] = min(m[i][i], 0LL);
Euler-Maclaurin formula for infinite sums: Cn = = − = rep(k,0,n) rep(i,0,n) rep(j,0,n)
∞ Z ∞ ∞ n+1 n n n+1 (n + 1)!n! if (m[i][k] != inf && m[k][j] != inf) {
X X Bk (k−1) auto newDist = max(m[i][k] + m[k][j], -inf);
f (i) = f (x)dx − f (m)
m k! 2(2n + 1) X m[i][j] = min(m[i][j], newDist);
i=m k=1 C0 = 1, Cn+1 = Cn , Cn+1 = Ci Cn−i }
Z ∞ f (m) f 0 (m) f 000 (m)
n+2
rep(k,0,n) if (m[k][k] < 0) rep(i,0,n) rep(j,0,n)
≈ f (x)dx + − + + O(f (5) (m)) Cn = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, . . . if (m[i][k] != inf && m[k][j] != inf) m[i][j] = -inf;
m 2 12 720
}
• sub-diagonal monotone paths in an n × n grid.
6.3.2 Stirling numbers of the first kind
• strings with n pairs of parenthesis, correctly nested.
Number of permutations on n items with k cycles. • binary trees with with n + 1 leaves (0 or 2 children).
• ordered trees with n + 1 vertices.
c(n, k) = c(n − 1, k − 1) + (n − 1)c(n − 1, k), c(0, 0) = 1 TopoSort.h
Pn • ways a convex polygon with n + 2 sides can be cut into
k Description: Topological sorting. Given is an oriented graph. Output is an
k=0 c(n, k)x = x(x + 1) . . . (x + n − 1) triangles by connecting vertices with straight lines. ordering of vertices, such that there are edges only from left to right. If there
c(8, k) = 8, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1 • permutations of [n] with no 3-term increasing subseq. are cycles, the returned list will have size smaller than n – nodes reachable
from cycles will not be returned.
c(n, 2) = 0, 0, 1, 3, 11, 50, 274, 1764, 13068, 109584, . . . Time: O (|V | + |E|)
Graph (7) vi topoSort(const vector<vi>& gr) {
66a137, 14 lines

6.3.3 Eulerian numbers vi indeg(sz(gr)), ret;


7.1 Fundamentals for (auto& li : gr) for (int x : li) indeg[x]++;
Number of permutations π ∈ Sn in which exactly k elements are queue<int> q; // use priority queue for l e x i c . l a r g e s t ans .
greater than the previous element. k j:s s.t. π(j) > π(j + 1), BellmanFord.h rep(i,0,sz(gr)) if (indeg[i] == 0) q.push(i);
Description: Calculates shortest paths from s in a graph that might have while (!q.empty()) {
k + 1 j:s s.t. π(j) ≥ j, k j:s s.t. π(j) > j. negative edge weights. Unreachable nodes get dist = inf; nodes reachable int i = q.front(); // top () for priority queue
through negative-weight cycles get dist = -inf. Assumes V 2 max |wi | < ∼263 . ret.push_back(i);
E(n, k) = (n − k)E(n − 1, k − 1) + (k + 1)E(n − 1, k) Time: O (V E) 830a8f, 23 lines q.pop();
for (int x : gr[i])
E(n, 0) = E(n, n − 1) = 1 const ll inf = LLONG_MAX;
if (--indeg[x] == 0) q.push(x);
struct Ed { int a, b, w, s() { return a < b ? a : -a; }};
k
! }
struct Node { ll dist = inf; int prev = -1; };
j n+1
X return ret;
E(n, k) = (−1) (k + 1 − j)n }
j=0
j void bellmanFord(vector<Node>& nodes, vector<Ed>& eds, int s) {
KTH PushRelabel MinCostMaxFlow EdmondsKarp MinCut GlobalMinCut 12
struct MaxFlowMinCost{
7.2 Network flow const ll Inf = 1e17;
int n, source, sink;
PushRelabel.h vector<ll> d;
Description: Push-relabel using the highest label selection rule and the gap vector<int> par;
vector<bool> inqueue;
heuristic. Quite fast in practice. To obtain the actual flow, look at positive vector<Edge> s;
values only.
 √  vector<vector<int>> adj;
Time: O V 2 E MaxFlowMinCost(int n){
0ae1d4, 48 lines this->n = n;
struct PushRelabel { s.reserve(n * 2); EdmondsKarp.h
struct Edge { d.resize(n + 5); Description: Flow algorithm with guaranteed complexity O(V E 2 ). To get
inqueue.resize(n + 5);
int dest, back; edge flow values, compare capacities before and after, and take the positive
par.resize(n + 5);
ll f, c; adj.resize(n + 5); values only. 482fe0, 35 lines
}; }
vector<vector<Edge>> g; void AddEdge(int u, int v, ll c, ll w){
template<class T> T edmondsKarp(vector<unordered_map<int, T>>&
vector<ll> ec; s.emplace_back(u, v, c, w); graph, int source, int sink) {
vector<Edge*> cur; adj[u].emplace_back(s.size() - 1); assert(source != sink);
vector<vi> hs; vi H; s.emplace_back(v, u, 0, -w); T flow = 0;
adj[v].emplace_back(s.size() - 1); vi par(sz(graph)), q = par;
PushRelabel(int n) : g(n), ec(n), cur(n), hs(2*n), H(n) {}
}
bool SPFA(){ for (;;) {
void addEdge(int s, int t, ll cap, ll rcap=0) { fill(d.begin(), d.end(), Inf);
if (s == t) return; fill(par.begin(), par.end(), s.size());
fill(all(par), -1);
g[s].push_back({t, sz(g[t]), 0, cap}); fill(inqueue.begin(), inqueue.end(), 0); par[source] = 0;
g[t].push_back({s, sz(g[s])-1, 0, rcap}); d[sink] = 0; int ptr = 1;
} queue<int> q; q[0] = source;
q.emplace(sink);
inqueue[sink] = 1; rep(i,0,ptr) {
void addFlow(Edge& e, ll f) { while (q.size()){
Edge &back = g[e.dest][e.back]; int x = q[i];
int c = q.front();
if (!ec[e.dest] && f) hs[H[e.dest]].push_back(e.dest); inqueue[c] = 0;
for (auto e : graph[x]) {
e.f += f; e.c -= f; ec[e.dest] += f; q.pop(); if (par[e.first] == -1 && e.second > 0) {
back.f -= f; back.c += f; ec[back.dest] -= f; for (auto i : adj[c]) par[e.first] = x;
} if (s[i ^ 1].c > 0 && d[s[i].v] > d[c] + s[i ^ 1].w){ q[ptr++] = e.first;
par[s[i].v] = i ^ 1; if (e.first == sink) goto out;
ll calc(int s, int t) {
d[s[i].v] = d[c] + s[i ^ 1].w; }
int v = sz(g); H[s] = v; ec[t] = 1; if (!inqueue[s[i].v]){
vi co(2*v); co[0] = v-1; }
q.emplace(s[i].v);
rep(i,0,v) cur[i] = g[i].data(); inqueue[s[i].v] = 1; }
for (Edge& e : g[s]) addFlow(e, e.c); } return flow;
} out:
for (int hi = 0;;) { } T inc = numeric_limits<T>::max();
return (d[source] < Inf); for (int y = sink; y != source; y = par[y])
while (hs[hi].empty()) if (!hi--) return -ec[s];
} inc = min(inc, graph[par[y]][y]);
int u = hs[hi].back(); hs[hi].pop_back(); pair<ll, ll> MaxFlow(int so, int t, ll k){
while (ec[u] > 0) // discharge u source = so;
if (cur[u] == g[u].data() + sz(g[u])) { sink = t; flow += inc;
H[u] = 1e9; ll Flow(0), cost(0); for (int y = sink; y != source; y = par[y]) {
for (Edge& e : g[u]) if (e.c && H[u] > H[e.dest]+1) while (k && SPFA()){ int p = par[y];
H[u] = H[e.dest]+1, cur[u] = &e; ll q(Inf); if ((graph[p][y] -= inc) <= 0) graph[p].erase(y);
int v = source; graph[y][p] += inc;
if (++co[H[u]], !--co[hi] && hi < v)
while (v != sink){ }
rep(i,0,v) if (hi < H[i] && H[i] < v) q = min(q, s[par[v]].c);
--co[H[i]], H[i] = v + 1; }
v = s[par[v]].v;
hi = H[u]; } }
} else if (cur[u]->c && H[u] == H[cur[u]->dest]+1) q = min(q, k);
addFlow(*cur[u], min(ec[u], cur[u]->c)); cost += d[source] * q; MinCut.h
else ++cur[u]; Flow += q;
k -= q;
Description: After running max-flow, the left side of a min-cut from s to t
} is given by all vertices reachable from s, only traversing edges with positive
v = source;
} while (v != sink){ residual capacity.
bool leftOfMinCut(int a) { return H[a] >= sz(g); } s[par[v]].c -= q;
}; s[par[v] ^ 1].c += q;
v = s[par[v]].v;
} GlobalMinCut.h
MinCostMaxFlow.h fe85cc, 81 lines } Description: Find a global minimum cut in an undirected graph, as repre-
return {Flow, cost}; sented by an adjacency matrix.
#include <bits/stdc++.h>
Time: O V 3

}
using namespace std; };
8b0e19, 21 lines
#define ll long long pair<int, vi> globalMinCut(vector<vi> mat) {
pair<int, vi> best = {INT_MAX, {}};
struct Edge{
int u, v; int n = sz(mat);
ll c, w; vector<vi> co(n);
Edge(const int &u, const int &v, const ll &c, const ll &w): u(u), v(v), rep(i,0,n) co[i] = {i};
c(c), w(w) {} rep(ph,1,n) {
}; vi w = mat[0];
size_t s = 0, t = 0;
KTH GomoryHu hopcroftKarp DFSMatching MinimumVertexCover WeightedMatching GeneralMatching 13
rep(it,0,n-ph) { // O(V^2) −> O(E log V) with prio . queue for (int a : cur) for (int b : g[a]) { if (mx[y] != 0)
w[t] = INT_MIN; if (btoa[b] == -1) { selX[mx[y]] = false;
s = t, t = max_element(all(w)) - w.begin(); B[b] = lay; }
rep(i,0,n) w[i] += mat[t][i]; islast = 1; for (int x = 1; x <= m; ++x)
} } if (selX[x]) resX.push_back(x);
return make_pair(selX, selY);
best = min(best, {w[t] - mat[t][t], co[t]}); else if (btoa[b] != a && !B[b]) { }
co[s].insert(co[s].end(), all(co[t])); B[b] = lay;
rep(i,0,n) mat[s][i] += mat[t][i]; next.push_back(btoa[b]);
rep(i,0,n) mat[i][s] = mat[s][i]; } WeightedMatching.h
mat[0][t] = INT_MIN; } Description: Given a weighted bipartite graph, matches every node on the
} if (islast) break; left with a node on the right such that no nodes are in two matchings and
return best; if (next.empty()) return res; the sum of the edge weights is minimal. Takes cost[N][M], where cost[i][j] =
} for (int a : next) A[a] = lay; cost for L[i] to be matched with R[j] and returns (min cost, match), where
cur.swap(next); L[i] is matched with R[match[i]]. Negate costs for max cost.
} Time: O N 2 M
GomoryHu.h

rep(a,0,sz(g)) 1e0fe9, 31 lines
Description: Given a list of edges representing an undirected flow graph,
res += dfs(a, 0, g, btoa, A, B); pair<int, vi> hungarian(const vector<vi> &a) {
returns edges of the Gomory-Hu tree. The max flow between any pair of
} if (a.empty()) return {0, {}};
vertices is given by minimum edge weight along the Gomory-Hu tree path.
} int n = sz(a) + 1, m = sz(a[0]) + 1;
Time: O (V ) Flow Computations
vi u(n), v(m), p(m), ans(n - 1);
"PushRelabel.h" 0418b3, 13 lines
DFSMatching.h MinimumVertexCover.h rep(i,1,n) {
typedef array<ll, 3> Edge; p[0] = i;
vector<Edge> gomoryHu(int N, vector<Edge> ed) { Description: In graph theory, a vertex cover (sometimes node cover) of a graph is a set int j0 = 0; // add ”dummy” worker 0
vector<Edge> tree; of vertices that includes at least one endpoint of every edge of the graph. The code list all vi dist(m, INT_MAX), pre(m, -1);
vi par(N); vertices in a vertex cover in a bipartite graph. vector<bool> done(m + 1);
rep(i,1,N) { Time: O (V E) do { // d i j k s t r a
PushRelabel D(N); // Dinic also works 522b98, 22 lines
done[j0] = true;
for (Edge t : ed) D.addEdge(t[0], t[1], t[2], t[2]); bool dfs(int u){ int i0 = p[j0], j1, delta = INT_MAX;
tree.push_back({i, par[i], D.calc(i, par[i])}); if (used[u] == cur) return 0;
rep(j,1,m) if (!done[j]) {
rep(j,i+1,N) used[u] = cur;
for (int v: adj[u]){ auto cur = a[i0 - 1][j - 1] - u[i0] - v[j];
if (par[j] == par[i] && D.leftOfMinCut(j)) par[j] = i; if (cur < dist[j]) dist[j] = cur, pre[j] = j0;
if (!mx[v] || dfs(mx[v])){
} mx[v] = u; if (dist[j] < delta) delta = dist[j], j1 = j;
return tree; my[u] = v; }
} return 1; rep(j,0,m) {
} if (done[j]) u[p[j]] += delta, v[j] -= delta;
}
return 0;
else dist[j] -= delta;
7.3 Matching } }
void dfs2(int u){ j0 = j1;
for (int v: adj[u]){ } while (p[j0]);
hopcroftKarp.h if (!avail[v]) continue; while (j0) { // update alternating path
Description: Fast bipartite matching algorithm. Graph g should be a list avail[v] = 0; int j1 = pre[j0];
of neighbors of the left partition, and btoa should be a vector full of -1’s of dfs2(mx[v]); p[j0] = p[j1], j0 = j1;
the same size as the right partition. Returns the size of the matching. btoa[i] }
}
}
will be the match for vertex i on the right side, or −1 if it’s not matched.
pair<vector<int>,vector<int>> VertexCover(){ }
Usage: vi √btoa(m, -1); hopcroftKarp(g, btoa);
 cin >> m >> n >> k; rep(j,1,m) if (p[j]) ans[p[j] - 1] = j - 1;
Time: O VE for (int i = 1; i <= k; ++i){ return {-v[0], ans}; // min cost
f612e4, 42 lines
int u, v; }
bool dfs(int a, int L, vector<vi>& g, vi& btoa, vi& A, vi& B) { cin >> u >> v;
if (A[a] != L) return 0; adj[u].pb(v);
A[a] = -1; } GeneralMatching.h
for (int b : g[a]) if (B[b] == L + 1) { iota(order + 1, order + m + 1, 1); Description: Matching for general graphs. Fails with probability N/mod.
B[b] = 0; shuffle(order + 1, order + m + 1, Rand); Time: O N 3
fill(avail + 1, avail + n + 1, 1); "../numerical/MatrixInverse-mod.h" cb1912, 40 lines
if (btoa[b] == -1 || dfs(btoa[b], L + 1, g, btoa, A, B)) int res = 0;
return btoa[b] = a, 1; for (cur = 1; cur <= m; ++cur){ vector<pii> generalMatching(int N, vector<pii>& ed) {
} if (!my[order[cur]]){ vector<vector<ll>> mat(N, vector<ll>(N)), A;
return 0; res += dfs(order[cur]); for (pii pa : ed) {
} } int a = pa.first, b = pa.second, r = rand() % mod;
} mat[a][b] = r, mat[b][a] = (mod - r) % mod;
int hopcroftKarp(vector<vi>& g, vi& btoa) { fill(used + 1, used + m + 1, 0); }
for (cur = 1; cur <= m; ++cur){
int res = 0; if (!my[order[cur]]) dfs2(order[cur]);
vi A(g.size()), B(btoa.size()), cur, next; } int r = matInv(A = mat), M = 2*N - r, fi, fj;
for (;;) { vector <int> resX, resY; assert(r % 2 == 0);
fill(all(A), 0); fill(selX + 1, selX + m + 1, false);
fill(all(B), 0); for (int y = 1; y <= n; ++y) if (M != N) do {
cur.clear(); if (mx[y] != 0) selX[mx[y]] = true; mat.resize(M, vector<ll>(M));
for (int a : btoa) if(a != -1) A[a] = -1; for (int y = 1; y <= n; ++y) rep(i,0,N) {
if (!avail[y])
rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a); {
mat[i].resize(M);
for (int lay = 1;; lay++) { resY.push_back(y); rep(j,N,M) {
bool islast = 0; int r = rand() % mod;
next.clear(); mat[i][j] = r, mat[j][i] = (mod - r) % mod;
KTH SCC BCC BiconnectedComponents 2sat EulerWalk 14
void add_edge(int u, int v) { low[u] = min(low[u], low[v]);
} adj[u].push_back(v); }
} adj[v].push_back(u); }
} while (matInv(A = mat) != M); } if(low[u] == num[u]){
void find_bcc() { nNode++;
vi has(M, 1); vector<pii> ret; for (int u = 1; u <= n; ++u) { while(!S.empty()){
if (num[u] == 0) { int v = S.back();
rep(it,0,M/2) {
dfs(u, -1); S.pop_back();
rep(i,0,M) if (has[i]) } node[v] = nNode;
rep(j,i+1,M) if (A[i][j] && mat[i][j]) { } num[v] = -1;
fi = i; fj = j; goto done; } if(v == u) break;
} assert(0); done: void dfs(int u, int p) { }
if (fj < N) ret.emplace_back(fi, fj); low[u] = num[u] = ++timedfs; }
has[fi] = has[fj] = 0; S.push_back(u); }
for (const int &i : adj[u]) { bool is_good(){
rep(sw,0,2) {
if (i == p) continue; for(int i=1; i<=n*2; i++)
ll a = modpow(A[fi][fj], mod-2); if (!num[i]) { if(!num[i]) dfs(i);
rep(i,0,M) if (has[i] && A[i][fj]) { dfs(i, u); for(int i=1; i<=n; i++)
ll b = A[i][fj] * a % mod; low[u] = min(low[u], low[i]); if(node[i] == node[rev(i)]) return false;
rep(j,0,M) A[i][j] = (A[i][j] - A[fi][j] * b) % mod; if (low[i] >= num[u]) { return true;
} ++bcc; }
swap(fi,fj); adj1[u].push_back(n + bcc); };
int v;
}
do { EulerWalk.h
} v = S.back(); Description: In graph theory, an Eulerian trail (or Eulerian path) is a trail in a finite
return ret; S.pop_back(); graph that visits every edge exactly once (allowing for revisiting vertices). Similarly, an
} adj1[bcc + n].push_back(v);
} while (v != i); Eulerian circuit or Eulerian cycle is an Eulerian trail that starts and ends on the same
} vertex. The code return the Eulerian path.
} else { Time: O (V + E)
7.4 DFS algorithms }
low[u] = min(low[u], num[i]);
struct TEdge{
} int u, v;
} bool del;
PseudoSCC }; };
Description: Finds strongly connected components in a directed graph. If vector <TEdge> e;
vertices u, v belong to the same component, we can reach u from v and vice 2sat.h vector <int> adj[maxN];
versa. void add_edge(int u, int v){
struct two_sat{
Time: O (E + V ) adj[u].pb(e.size());
76b5c9, 24 lines static constexpr int N = 1e6 + 5;
adj[v].pb(e.size());
int n;
index := 0 e.pb({u, v, 0});
vector<int> adj[N];
S := empty stack }
int vis[N], low[N], num[N], Time = 0, node[N], nNode = 0;
for each v in V do vector <int> euler(int s){
vector<int> S;
if v.index is undefined then vector <int> res;
void init(int _n){
strongconnect(v) vector <int> S(1, s);
n = _n;
function strongconnect(v) while (!S.empty()){
Time = nNode = 0;
v.index := index int u = S.back();
for(int i=0; i<=n*2; i++){
v.lowlink := index while (!adj[u].empty() && e[adj[u].back()].del) adj[u].pop_back();
vis[i] = 0;
index := index + 1 if (!adj[u].empty()){
low[i] = num[i] = 0;
S.push(v) auto &i = e[adj[u].back()];
node[i] = 0;
v.onStack := true S.pb(i.u ^ i.v ^ u);
adj[i].clear();
for each (v, w) in E do i.del = 1;
}
if w.index is undefined then adj[u].pop_back();
S.clear();
strongconnect(w) }
}
v.lowlink := min(v.lowlink, w.lowlink) else{
int rev(int a){
else if w.onStack then res.pb(u);
if(a <= n) return a + n;
v.lowlink := min(v.lowlink, w.index) S.pop_back();
else return a - n;
if v.lowlink = v.index then }
}
start a new strongly connected component }
void add_edge(int a, int b){
repeat return res;
adj[rev(a)].pb(b);
w := S.pop() }
adj[rev(b)].pb(a);
w.onStack := false } 7.5 Coloring
add w to current strongly connected component void add_or(int a, int b){ // a || b = 1
while w ≠ v add_edge(a, b);
output the current strongly connected component } EdgeColoring.h
void add_xor(int a, int b){ // a + b = 1 Description: Given a simple, undirected graph with max degree D, com-
BiconnectedComponents.h add_or(a, b); putes a (D + 1)-coloring of the edges such that no neighboring edges share
add_or(rev(a), rev(b));
Description: Build a virtual tree that every BCC is virtual nodes. (For vertex blocking }
a color. (D-coloring is NP-hard, but can be done for bipartite graphs by
problems) void add_and(int a, int b){ // a = b repeated matchings of max-degree nodes.)
add_xor(a, rev(b)); Time: O (N M )
For bridge blocking problems, use Tarjan in SCC above e210e2, 31 lines
}
Time: O (E + V ) void dfs(int u){ vi edgeColoring(int N, vector<pii> eds) {
2965e5, 33 lines
S.pb(u); vi cc(N + 1), ret(sz(eds)), fan(N), free(N), loc;
struct BCC {
low[u] = num[u] = ++Time; for (pii e : eds) ++cc[e.first], ++cc[e.second];
vector<int> num, low, S;
for(int v : adj[u]){ int u, v, ncols = *max_element(all(cc)) + 1;
vector<vector<int>> adj, adj1;
if(num[v] == -1) continue; vector<vi> adj(N, vi(ncols, -1));
int timedfs, bcc, n;
if(num[v]) low[u] = min(low[u], num[v]);
BCC(int n) : num(n + 10), low(n + 10), adj(n + 10), adj1(n), for (pii e : eds) {
else{
timedfs(0), bcc(0), n(n) {} tie(u, v) = e;
dfs(v);
fan[0] = v;
KTH EdgeColoring MaximalCliques MaximumClique MaximumIndependentSet BinaryLifting LCA CompressTree XorSegmentTree 15
void init(vv& r) { void contract(int c, int x, int y, vector<int> &vx, vector<int> &vy){
loc.assign(ncols, 0); b[c].clear();
int at = u, end = u, d, c = free[u], ind = 0, i = 0; for (auto& v : r) v.d = 0;
int r = vx.back();
while (d = free[v], !loc[d] && (v = adj[u][d]) != -1) for (auto& v : r) for (auto j : r) v.d += e[v.i][j.i]; while(!vx.empty() && !vy.empty() && vx.back() == vy.back()){
loc[d] = ++ind, cc[ind] = d, fan[ind] = v; sort(all(r), [](auto a, auto b) { return a.d > b.d; }); r = vx.back(); vx.pop_back(); vy.pop_back();
cc[loc[d]] = c; int mxD = r[0].d; }
for (int cd = d; at != -1; cd ^= c ^ d, at = adj[at][cd]) rep(i,0,sz(r)) r[i].d = min(i, mxD) + 1; b[c].push_back(r);
swap(adj[at][cd], adj[end = at][cd ^ c ^ d]); } b[c].insert(b[c].end(), vx.rbegin(), vx.rend());
void expand(vv& R, int lev = 1) { b[c].insert(b[c].end(), vy.begin(), vy.end());
while (adj[fan[i]][d] != -1) { for(int i = 0; i <= c; i++){
int left = fan[i], right = fan[++i], e = cc[i]; S[lev] += S[lev - 1] - old[lev];
g[c][i] = g[i][c] = -1;
adj[u][e] = left; old[lev] = S[lev - 1]; }
adj[left][e] = u; while (sz(R)) { for(int z : b[c]){
adj[right][e] = -1; if (sz(q) + R.back().d <= sz(qmax)) return; bl[z] = c;
free[right] = e; q.push_back(R.back().i); for(int i = 0; i < c; i++){
} vv T; if(g[z][i] != -1){
for(auto v:R) if (e[R.back().i][v.i]) T.push_back({v.i}); g[c][i] = z; g[i][c] = g[i][z];
adj[u][d] = fan[i]; }
adj[fan[i]][d] = u; if (sz(T)) {
}
for (int y : {fan[0], u, end}) if (S[lev]++ / ++pk < limit) init(T); }
for (int& z = free[y] = 0; adj[y][z] != -1; z++); int j = 0, mxk = 1, mnk = max(sz(qmax) - sz(q) + 1, 1); }
} C[1].clear(), C[2].clear(); vector<int> lift(vector<int> &vx){
rep(i,0,sz(eds)) for (auto v : T) { vector<int> A;
for (tie(u, v) = eds[i]; adj[u][ret[i]] != v;) ++ret[i]; int k = 1; while(vx.size() >= 2){
auto f = [&](int i) { return e[v.i][i]; }; int z = vx.back(); vx.pop_back();
return ret; if(z < n){
} while (any_of(all(C[k]), f)) k++;
A.push_back(z); continue;
if (k > mxk) mxk = k, C[mxk + 1].clear(); }
if (k < mnk) T[j++].i = v.i; int w = vx.back();
C[k].push_back(v.i); int i = (A.size() % 2 == 0 ? find(b[z].begin(), b[z].end(), g[z][w
7.6 Heuristics } ]) - b[z].begin() : 0);
int j = (A.size() % 2 == 1 ? find(b[z].begin(), b[z].end(), g[z]
if (j > 0) T[j - 1].d = 0;
MaximalCliques.h rep(k,mnk,mxk + 1) for (int i : C[k]) [A.back()]) - b[z].begin() : 0);
  int k = b[z].size();
Time: O 3n/ T[j].i = i, T[j++].d = k;
, much faster for sparse graphs int dif = (A.size() % 2 == 0 ? i % 2 == 1 : j % 2 == 0) ? 1 : k -
b0d5b1, 12 lines expand(T, lev + 1); 1;
int get(ll t){// find last bit 1 } else if (sz(q) > sz(qmax)) qmax = q; while(i != j){
return Log2(t & -t); q.pop_back(), R.pop_back(); vx.push_back(b[z][i]); i = (i + dif) % k;
} } }
int res = 0; } vx.push_back(b[z][i]);
void clique(ll c, ll u){// c : vertices in clique, u : candidate vertices vi maxClique() { init(V), expand(V); return qmax; } }
if(u == 0){ return A;
if(__builtin_popcountll(c) > __builtin_popcountll(res)) res = c;
Maxclique(vb conn) : e(conn), C(sz(e)+1), S(sz(C)), old(S) {
}
return; rep(i,0,sz(e)) V.push_back({i}); int solve(){
} } for(int ans = 0; ; ans++){
ll num1 = __builtin_popcountll(c); }; fill(d.begin(), d.end(), 0);
ll num2 = __builtin_popcountll(u); queue<int> Q;
if(num1 + num2 < __builtin_popcountll(res)) return; for(int i = 0; i < m; i++) bl[i] = i;
ll t = get(u); MaximumIndependentSet.h for(int i = 0; i < n; i++){
clique(c | (1LL << t), (u ^ (1LL << t)) & adj[t]); Description: To obtain a maximum independent set of a graph, find a max if(mate[i] == -1){
clique(c, u ^ (1LL << t)); clique of the complement. If the graph is bipartite, see MinimumVertexCover. Q.push(i); p[i] = i; d[i] = 1;
} }
int f(int mask){// return maximal clique GeneralMatching.h }
res = 0; Description: Edmonds Blossom algorithm O(n^3) to find maximum matching in general int c = n;
clique(0, mask); bool aug = false;
return res; graph. For bipartite graph, use DFS matching instead while(!Q.empty() && !aug){
} struct blossom{ int x = Q.front(); Q.pop();
int Cal(int mask){// return size of maximal clique int n, m; if(bl[x] != x) continue;
return __builtin_popcountll(f(mask)); vector<int> mate, p, d, bl; for(int y = 0; y < c; y++){
} vector<vector<int>> b, g; if(bl[y] == y && g[x][y] != -1){
blossom(int n) : n(n){ if(d[y] == 0){
MaximumClique.h m = n + n / 2; mate.assign(n, -1); p[y] = x; d[y] = 2;
Description: Quickly finds a maximum clique of a graph (given as symmet- b.resize(m); p.resize(m); d.resize(m); bl.resize(m); p[mate[y]] = y; d[mate[y]] = 1;
ric bitset matrix; self-edges not allowed). Can be used to find a maximum g.assign(m, vector<int>(m, -1)); Q.push(mate[y]);
independent set by finding a clique of the complement graph. } }
void add_edge(int u, int v){ else if(d[y] == 1){
Time: Runs in about 1s for n=155 and worst case random graphs (p=.90). vector<int> vx = trace(x);
g[u][v] = u; g[v][u] = v;
Runs faster for sparse graphs. f7c0bc, 49 lines } vector<int> vy = trace(y);
void match(int u, int v){ if(vx.back() == vy.back()){
typedef vector<bitset<200>> vb; contract(c, x, y, vx, vy);
g[u][v] = g[v][u] = -1; mate[u] = v; mate[v] = u;
struct Maxclique { } Q.push(c);
double limit=0.025, pk=0; vector<int> trace(int x){ p[c] = p[b[c][0]]; d[c] = 1;
struct Vertex { int i, d=0; }; vector<int> vx; c++;
typedef vector<Vertex> vv; while(true){ }
vb e; while(bl[x] != x) x = bl[x]; else{
if(!vx.empty() && vx.back() == x) break; aug = true;
vv V; vx.insert(vx.begin(), y);
vector<vi> C; vx.push_back(x); x = p[x];
} vy.insert(vy.begin(), x);
vi qmax, q, S, old; return vx; vector<int> A = lift(vx);
} vector<int> B = lift(vy);
KTH A.insert(A.end(), B.rbegin(), B.rend());
HLD LinkCutTree DirectedMST 16
for(int i = 0; i < (int) A.size(); i += 2){
match(A[i], A[i + 1]); 7.7 Trees }
if(i + 2 < (int) A.size()) add_edge(A[i + bool connected(int u, int v) { // are u, v in the same tree?
1], A[i + 2]);
LinkCutTree.h Node* nu = access(&node[u])->first();
} Description: Represents a forest of unrooted trees. You can add and re-
move edges (as long as the result is still a forest), and check whether two return nu == access(&node[v])->first();
} }
break; nodes are in the same tree.
} Time: All operations take amortized O (log N ). void makeRoot(Node* u) {
5909e2, 90 lines access(u);
}
} struct Node { // Splay tree . Root ’ s pp contains tree ’ s parent . u->splay();
} Node *p = 0, *pp = 0, *c[2]; if(u->c[0]) {
if(!aug) return ans; bool flip = 0; u->c[0]->p = 0;
} Node() { c[0] = c[1] = 0; fix(); } u->c[0]->flip ^= 1;
} u->c[0]->pp = u;
void fix() {
};
if (c[0]) c[0]->p = this; u->c[0] = 0;
XorSegmentTree.h if (c[1]) c[1]->p = this; u->fix();
Description: Applicable for problems required operations on XOR indexes (e.g: // (+ update sum of subtree elements etc . i f wanted) }
a[l ^ x], a[(l + 1) ^ x], ... Query update is only available if Merge(id, id + 1) = } }
Merge(id + 1, id) (Commutative) void pushFlip() { Node* access(Node* u) {
Time: O(logn) for update and O(logn) for get if (!flip) return; u->splay();
#include <bits/stdc++.h> flip = 0; swap(c[0], c[1]); while (Node* pp = u->pp) {
#define ll long long if (c[0]) c[0]->flip ^= 1; pp->splay(); u->pp = 0;
#define pb push_back if (c[1]) c[1]->flip ^= 1; if (pp->c[1]) {
using namespace std; } pp->c[1]->p = 0; pp->c[1]->pp = pp; }
const int maxN = 1e5 + 1; int up() { return p ? p->c[1] == this : -1; } pp->c[1] = u; pp->fix(); u = pp;
int a[maxN]; void rot(int i, int b) { }
struct XORSegtree{ return u;
int h = i ^ b;
vector<int> st[4 * maxN];
int lazy[4 * maxN]; Node *x = c[i], *y = b == 2 ? x : x->c[h], *z = b ? y : x; }
XORSegtree(){ if ((y->p = p)) p->c[up()] = y; };
for(int i=0; i<4*maxN; i++){ c[i] = z->c[i ^ 1];
st[i].clear(); if (b < 2) { DirectedMST.h
lazy[i] = 0; x->c[h] = y->c[h ^ 1]; Description: Finds a minimum spanning tree/arborescence of a directed
} z->c[h ^ 1] = b ? x : this;
} graph, given a root node. If no MST exists, returns -1.
} Time: O (E log V )
void build(int id, int l, int r){
lazy[id] = 0; y->c[i ^ 1] = b ? this : x; "../data-structures/UnionFindRollback.h" 39e620, 60 lines
st[id].clear(); fix(); x->fix(); y->fix();
struct Edge { int a, b; ll w; };
if(l == r){ if (p) p->fix();
struct Node {
st[id].pb(a[l]); swap(pp, y->pp);
return; Edge key;
}
} Node *l, *r;
void splay() {
int mid = (l + r) / 2; ll delta;
for (pushFlip(); p; ) {
build(id * 2, l, mid); void prop() {
build(id * 2 + 1, mid + 1, r); if (p->p) p->p->pushFlip();
key.w += delta;
int len = r - l + 1; p->pushFlip(); pushFlip();
if (l) l->delta += delta;
st[id].resize(len); int c1 = up(), c2 = p->up();
for(int i=0; i<len; i++){
if (r) r->delta += delta;
if (c2 == -1) p->rot(c1, 2);
if(i >= len / 2) st[id][i] = st[id * 2][i - len / 2] + st[id * 2 + delta = 0;
else p->p->rot(c2, c1 != c2);
1][i - len / 2]; }
}
else st[id][i] = st[id * 2 + 1][i] + st[id * 2][i]; Edge top() { prop(); return key; }
}
} };
} Node* first() {
Node *merge(Node *a, Node *b) {
void update(int id, int l, int r, int pos, int val){ pushFlip();
if (!a || !b) return a ?: b;
lazy[id] += val; return c[0] ? c[0]->first() : (splay(), this);
if(l == r) return;
a->prop(), b->prop();
}
int mid = (l + r) / 2; if (a->key.w > b->key.w) swap(a, b);
};
if(pos <= mid) update(id * 2, l, mid, pos, val); swap(a->l, (a->r = merge(b, a->r)));
else update(id * 2 + 1, mid + 1, r, pos, val); return a;
struct LinkCut {
} }
int get(int id, int l, int r, int u, int v, int x, int depth) vector<Node> node;
void pop(Node*& a) { a->prop(); a = merge(a->l, a->r); }
{ LinkCut(int N) : node(N) {}
if(l > v | r < u) return 0;
if(l >= u && r <= v){
pair<ll, vi> dmst(int n, int r, vector<Edge>& g) {
void link(int u, int v) { // add an edge (u, v)
return lazy[id] + st[id][x & ((1 << depth) - 1)]; RollbackUF uf(n);
assert(!connected(u, v));
} vector<Node*> heap(n);
makeRoot(&node[u]);
int mid = (l + r) / 2; for (Edge e : g) heap[e.b] = merge(heap[e.b], new Node{e});
node[u].pp = &node[v];
if(x >> (depth - 1) & 1){ ll res = 0;
return get(id * 2 + 1, mid + 1, r, u - l + (mid + 1), v - l + (mid }
vi seen(n, -1), path(n), par(n);
+ 1), x, depth - 1) + void cut(int u, int v) { // remove an edge (u, v)
seen[r] = r;
get(id * 2, l, mid, l + u - (mid + 1), l + v - (mid + 1), x, Node *x = &node[u], *top = &node[v];
depth - 1);
vector<Edge> Q(n), in(n, {-1,-1}), comp;
makeRoot(top); x->splay();
} deque<tuple<int, int, vector<Edge>>> cycs;
assert(top == (x->pp ?: x->c[0]));
else{ rep(s,0,n) {
if (x->pp) x->pp = 0;
return get(id * 2, l, mid, u, v, x, depth - 1) + get(id * 2 + 1, int u = s, qi = 0, w;
mid + 1, r, u, v, x, depth - 1);
else {
while (seen[u] < 0) {
} x->c[0] = top->p = 0;
if (!heap[u]) return {-1,{}};
} x->fix();
Edge e = heap[u]->top();
}; }
KTH Point lineDistance SegmentDistance SegmentIntersection lineIntersection sideOf OnSegment linearTransformation 17
heap[u]->delta -= e.w, pop(heap[u]); P operator-(P p) const { return P(x-p.x, y-p.y); } // Checks i f intersection i s single non−endpoint point .
Q[qi] = e, path[qi++] = u, seen[u] = s; P operator*(T d) const { return P(x*d, y*d); } if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn(od) < 0)
res += e.w, u = uf.find(e.a); P operator/(T d) const { return P(x/d, y/d); } return {(a * ob - b * oa) / (ob - oa)};
if (seen[u] == s) { T dot(P p) const { return x*p.x + y*p.y; } set<P> s;
Node* cyc = 0; T cross(P p) const { return x*p.y - y*p.x; } if (onSegment(c, d, a)) s.insert(a);
int end = qi, time = uf.time(); T cross(P a, P b) const { return (a-*this).cross(b-*this); } if (onSegment(c, d, b)) s.insert(b);
do cyc = merge(cyc, heap[w = path[--qi]]); T dist2() const { return x*x + y*y; } if (onSegment(a, b, c)) s.insert(c);
while (uf.join(u, w)); double dist() const { return sqrt((double)dist2()); } if (onSegment(a, b, d)) s.insert(d);
u = uf.find(u), heap[u] = cyc, seen[u] = -1; // angle to x−axis in interval [−pi , pi ] return {all(s)};
cycs.push_front({u, time, {&Q[qi], &Q[end]}}); double angle() const { return atan2(y, x); } }
} P unit() const { return *this/dist(); } // makes d i s t ()=1
} P perp() const { return P(-y, x); } // rotates +90 degrees
rep(i,0,qi) in[uf.find(Q[i].b)] = Q[i]; P normal() const { return perp().unit(); }
lineIntersection.h
Description:
} // returns point rotated ’a ’ radians ccw around the origin
If a unique intersection point of the lines going through s1,e1
P rotate(double a) const {
and s2,e2 exists {1, point} is returned. If no intersection point
for (auto& [u,t,comp] : cycs) { // restore s o l ( optional ) return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
exists {0, (0,0)} is returned and if infinitely many exists {-1, e2 r
uf.rollback(t); friend ostream& operator<<(ostream& os, P p) {
(0,0)} is returned. The wrong position will be returned if P
Edge inEdge = in[u]; return os << "(" << p.x << "," << p.y << ")"; }
is Point<ll> and the intersection point does not have inte- e1 s2
ger coordinates. Products of three coordinates are used in s1
for (auto& e : comp) in[uf.find(e.b)] = e; };
in[uf.find(inEdge.b)] = inEdge;
intermediate steps so watch out for overflow if using int or ll.
}
rep(i,0,n) par[i] = in[i].a;
lineDistance.h Usage: auto res = lineInter(s1,e1,s2,e2);
Description: if (res.first == 1)
return {res, par}; cout << "intersection point at " << res.second << endl;
Returns the signed distance between point p and the line con-
}
taining points a and b. Positive value on left side and negative "Point.h" a01f81, 8 lines
on right as seen from a towards b. a==b gives nan. P is sup-
res
template<class P>
posed to be Point<T> or Point3D<T> where T is e.g. double e p
7.8 Math or long long. It uses products in intermediate steps so watch
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
auto d = (e1 - s1).cross(e2 - s2);
out for overflow if using int or long long. Using Point3D will if (d == 0) // i f p a r a l l e l
7.8.1 Number of Spanning Trees always give a non-negative distance. For Point3D, call .dist s return {-(s1.cross(e1, s2) == 0), P(0, 0)};
on the result of the cross product. auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
Create an N × N matrix mat, and for each edge a → b ∈ G, do "Point.h" f6bf6b, 4 lines
return {1, (s1 * p + e1 * q) / d};
mat[a][b]--, mat[b][b]++ (and mat[b][a]--, template<class P> }
double lineDist(const P& a, const P& b, const P& p) {
mat[a][a]++ if G is undirected). Remove the ith row and return (double)(b-a).cross(p-a)/(b-a).dist();
column and take the determinant; this yields the number of } sideOf.h
Description: Returns where p is as seen from s towards e. 1/0/-1 ⇔ left/on
directed spanning trees rooted at i (if G is undirected, remove
e res p
line/right. If the optional argument eps is given 0 is returned if p is within
any row/column). SegmentDistance.h distance eps from the line. P is supposed to be Point<T> where T is e.g.
Description: double or long long. It uses products in intermediate steps so watch out for
Returns the shortest distance between point p and the line overflow if using int or long long.
7.8.2 Erdős–Gallai theorem segment from point s to e. s Usage: bool left = sideOf(p1,p2,q)==1;
Usage: Point<double> a, b(2,2), p(1,1); "Point.h" 3af81c, 9 lines
A simple graph with node degrees d1 ≥ · · · ≥ dn exists iff bool onSegment = segDist(a,b,p) < 1e-10;
"Point.h" 5c88f4, 6 lines
template<class P>
d1 + · · · + dn is even and for every k = 1 . . . n, typedef Point<double> P;
int sideOf(P s, P e, P p) { return sgn(s.cross(e, p)); }

k n double segDist(P& s, P& e, P& p) { template<class P>


X X if (s==e) return (p-s).dist(); int sideOf(const P& s, const P& e, const P& p, double eps) {
di ≤ k(k − 1) + min(di , k). auto d = (e-s).dist2(), t = min(d,max(.0,(p-s).dot(e-s))); auto a = (e-s).cross(p-s);
i=1 i=k+1 return ((p-s)*d-(e-s)*t).dist()/d; double l = (e-s).dist()*eps;
} return (a > l) - (a < -l);
}
SegmentIntersection.h
Geometry (8) Description: OnSegment.h
If a unique intersection point between the line segments going
Description: Returns true iff p lies on the line segment from s to e. Use
8.1 Geometric primitives from s1 to e1 and from s2 to e2 exists then it is returned.
(segDist(s,e,p)<=epsilon) instead when using Point<double>.
If no intersection point exists an empty vector is returned. e1 "Point.h" c597e8, 3 lines
If infinitely many exist a vector with 2 elements is returned,
containing the endpoints of the common line segment. The e2
Point.h template<class P> bool onSegment(P s, P e, P p) {
Description: Class to handle points in the plane. T can be e.g. double or
wrong position will be returned if P is Point<ll> and the in- r1 return p.cross(s, e) == 0 && (s - p).dot(e - p) <= 0;
long long. (Avoid int.) 47ec0a, 28 lines tersection point does not have integer coordinates. Products
s1 s2 }
of three coordinates are used in intermediate steps so watch
template <class T> int sgn(T x) { return (x > 0) - (x < 0); }
out for overflow if using int or long long. r p1
template<class T> linearTransformation.h
struct Point { Usage: vector<P> inter = segInter(s1,e1,s2,e2); Description:
typedef Point P; if (sz(inter)==1) p0 res
T x, y; cout << "segments intersect at " << inter[0] << endl; Apply the linear transformation (translation, rotation and q0
explicit Point(T x=0, T y=0) : x(x), y(y) {} "Point.h", "OnSegment.h" 9d57f2, 13 lines scaling) which takes line p0-p1 to line q0-q1 to point r. q1
bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); } template<class P> vector<P> segInter(P a, P b, P c, P d) { "Point.h" 03a306, 6 lines

bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); } auto oa = c.cross(d, a), ob = c.cross(d, b), typedef Point<double> P;
P operator+(P p) const { return P(x+p.x, y+p.y); } oc = a.cross(b, c), od = a.cross(b, d); P linearTransformation(const P& p0, const P& p1,
KTH Angle CircleIntersection CircleTangents CirclePolygonIntersection circumcircle MinimumEnclosingCircle InsidePolygon PolygonArea PolygonCenter 18
const P& q0, const P& q1, const P& r) { CircleTangents.h MinimumEnclosingCircle.h
P dp = p1-p0, dq = q1-q0, num(dp.cross(dq), dp.dot(dq)); Description: Finds the external tangents of two circles, or internal if r2 is Description: Computes the minimum circle that encloses a set of points.
return q0 + P((r-p0).cross(num), (r-p0).dot(num))/dp.dist2(); negated. Can return 0, 1, or 2 tangents – 0 if one circle contains the other (or Time: expected O (n)
} overlaps it, in the internal case, or if the circles are the same); 1 if the circles "circumcircle.h" 09dd0a, 17 lines
are tangent to each other (in which case .first = .second and the tangent line pair<P, double> mec(vector<P> ps) {
is perpendicular to the line between the centers). .first and .second give the
Angle.h tangency points at circle 1 and 2 respectively. To find the tangents of a circle
shuffle(all(ps), mt19937(time(0)));
Description: A class for ordering angles (as represented by int points and P o = ps[0];
with a point set r2 to 0. double r = 0, EPS = 1 + 1e-8;
a number of rotations around the origin). Useful for rotational sweeping.
"Point.h" b0153d, 13 lines rep(i,0,sz(ps)) if ((o - ps[i]).dist() > r * EPS) {
Sometimes also represents points or vectors.
Usage: vector<Angle> v = {w[0], w[0].t360() ...}; // sorted template<class P> o = ps[i], r = 0;
int j = 0; rep(i,0,n) { while (v[j] < v[i].t180()) ++j; } vector<pair<P, P>> tangents(P c1, double r1, P c2, double r2) { rep(j,0,i) if ((o - ps[j]).dist() > r * EPS) {
// sweeps j such that (j-i) represents the number of positively P d = c2 - c1; o = (ps[i] + ps[j]) / 2;
oriented triangles with vertices at 0 and i double dr = r1 - r2, d2 = d.dist2(), h2 = d2 - dr * dr; r = (o - ps[i]).dist();
0f0602, 35 lines
if (d2 == 0 || h2 < 0) return {}; rep(k,0,j) if ((o - ps[k]).dist() > r * EPS) {
struct Angle { vector<pair<P, P>> out; o = ccCenter(ps[i], ps[j], ps[k]);
int x, y; for (double sign : {-1, 1}) { r = (o - ps[i]).dist();
int t; P v = (d * dr + d.perp() * sqrt(h2) * sign) / d2; }
Angle(int x, int y, int t=0) : x(x), y(y), t(t) {} out.push_back({c1 + v * r1, c2 + v * r2}); }
Angle operator-(Angle b) const { return {x-b.x, y-b.y, t}; } } }
int half() const { if (h2 == 0) out.pop_back(); return {o, r};
assert(x || y); return out; }
return y < 0 || (y == 0 && x < 0); }
}
Angle t90() const { return {-y, x, t + (half() && x >= 0)}; }
Angle t180() const { return {-x, -y, t + half()}; }
8.3 Polygons
Angle t360() const { return {x, y, t + 1}; } CirclePolygonIntersection.h
}; Description: Returns the area of the intersection of a circle with a ccw InsidePolygon.h
bool operator<(Angle a, Angle b) { polygon. Description: Returns true if p lies within the polygon. If strict is true, it
// add a . dist2 () and b . dist2 () to also compare distances Time: O (n) returns false for points on the boundary. The algorithm uses products in
return make_tuple(a.t, a.half(), a.y * (ll)b.x) < "../../content/geometry/Point.h" a1ee63, 19 lines intermediate steps so watch out for overflow.
make_tuple(b.t, b.half(), a.x * (ll)b.y); Usage: vector<P> v = {P{4,4}, P{1,2}, P{2,1}};
typedef Point<double> P;
} bool in = inPolygon(v, P{3, 3}, false);
#define arg(p, q) atan2(p.cross(q), p.dot(q))
Time: O (n)
double circlePoly(P c, double r, vector<P> ps) {
// Given two points , t h i s calculates the smallest angle between auto tri = [&](P p, P q) {
"Point.h", "OnSegment.h", "SegmentDistance.h" 2bf504, 11 lines
// them, i . e . , the angle that covers the defined l i n e segment . auto r2 = r * r / 2; template<class P>
pair<Angle, Angle> segmentAngles(Angle a, Angle b) { P d = q - p; bool inPolygon(vector<P> &p, P a, bool strict = true) {
if (b < a) swap(a, b); auto a = d.dot(p)/d.dist2(), b = (p.dist2()-r*r)/d.dist2(); int cnt = 0, n = sz(p);
return (b < a.t180() ? auto det = a * a - b; rep(i,0,n) {
make_pair(a, b) : make_pair(b, a.t360())); if (det <= 0) return arg(p, q) * r2; P q = p[(i + 1) % n];
} auto s = max(0., -a-sqrt(det)), t = min(1., -a+sqrt(det)); if (onSegment(p[i], q, a)) return !strict;
Angle operator+(Angle a, Angle b) { // point a + vector b if (t < 0 || 1 <= s) return arg(p, q) * r2; //or : i f ( segDist (p [ i ] , q , a) <= eps) return ! s t r i c t ;
Angle r(a.x + b.x, a.y + b.y, a.t); P u = p + d * s, v = p + d * t; cnt ^= ((a.y<p[i].y) - (a.y<q.y)) * a.cross(p[i], q) > 0;
if (a.t180() < r) r.t--; return arg(p,u) * r2 + u.cross(v)/2 + arg(v,q) * r2; }
return r.t180() < a ? r.t360() : r; }; return cnt;
} auto sum = 0.0; }
Angle angleDiff(Angle a, Angle b) { // angle b − angle a rep(i,0,sz(ps))
int tu = b.t - a.t; a.t = b.t;
return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x, tu - (b < a)};
sum += tri(ps[i] - c, ps[(i + 1) % sz(ps)] - c); PolygonArea.h
return sum; Description: Returns twice the signed area of a polygon. Clockwise enu-
} } meration gives negative area. Watch out for overflow if using int as T!
"Point.h" f12300, 6 lines
template<class T>
8.2 Circles T polygonArea2(vector<Point<T>>& v) {
circumcircle.h T a = v.back().cross(v[0]);
Description:
CircleIntersection.h B rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]);
Description: Computes the pair of points at which two circles intersect. The circumcirle of a triangle is the circle intersecting all return a;
Returns false in case of no intersection. three vertices. ccRadius returns the radius of the circle going r c }
"Point.h" 84d6d3, 11 lines through points A, B and C and ccCenter returns the center C
of the same circle. A
typedef Point<double> P;
"Point.h" 1caa3a, 9 lines
PolygonCenter.h
bool circleInter(P a,P b,double r1,double r2,pair<P, P>* out) { Description: Returns the center of mass for a polygon.
if (a == b) { assert(r1 != r2); return false; } typedef Point<double> P; Time: O (n)
P vec = b - a; double ccRadius(const P& A, const P& B, const P& C) { "Point.h" 9706dc, 9 lines
double d2 = vec.dist2(), sum = r1+r2, dif = r1-r2, return (B-A).dist()*(C-B).dist()*(A-C).dist()/
typedef Point<double> P;
p = (d2 + r1*r1 - r2*r2)/(d2*2), h2 = r1*r1 - p*p*d2; abs((B-A).cross(C-A))/2;
P polygonCenter(const vector<P>& v) {
if (sum*sum < d2 || dif*dif > d2) return false; }
P res(0, 0); double A = 0;
P mid = a + vec*p, per = vec.perp() * sqrt(fmax(0, h2) / d2); P ccCenter(const P& A, const P& B, const P& C) {
for (int i = 0, j = sz(v) - 1; i < sz(v); j = i++) {
*out = {mid + per, mid - per}; P b = C-A, c = B-A;
res = res + (v[i] + v[j]) * v[j].cross(v[i]);
return true; return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2;
A += v[j].cross(v[i]);
} }
}
KTH PolygonCut ConvexHull HullDiameter PointInsideHull LineHullIntersection ClosestPair kdTree 19
return res / A / 3; Time: O (log N ) 8.4 Misc. Point Set Problems
} "Point.h", "sideOf.h", "OnSegment.h" 71446b, 14 lines

typedef Point<ll> P; ClosestPair.h


PolygonCut.h e Description: Finds the closest pair of points.
bool inHull(const vector<P>& l, P p, bool strict = true) { Time: O (n log n)
Description:
int a = 1, b = sz(l) - 1, r = !strict; "Point.h" ac41a6, 17 lines
Returns a vector with the vertices of a polygon with every-
if (sz(l) < 3) return r && onSegment(l[0], l.back(), p);
thing to the left of the line going from s to e cut away. typedef Point<ll> P;
if (sideOf(l[0], l[a], l[b]) > 0) swap(a, b);
Usage: vector<P> p = ...; s if (sideOf(l[0], l[a], p) >= r || sideOf(l[0], l[b], p)<= -r)
pair<P, P> closest(vector<P> v) {
p = polygonCut(p, P(0,0), P(1,0)); assert(sz(v) > 1);
return false;
"Point.h", "lineIntersection.h" f2b7d4, 13 lines set<P> S;
while (abs(a - b) > 1) {
typedef Point<double> P; sort(all(v), [](P a, P b) { return a.y < b.y; });
int c = (a + b) / 2;
vector<P> polygonCut(const vector<P>& poly, P s, P e) { pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P()}};
(sideOf(l[0], l[c], p) > 0 ? b : a) = c;
vector<P> res; int j = 0;
}
rep(i,0,sz(poly)) { for (P p : v) {
return sgn(l[a].cross(l[b], p)) < r;
P cur = poly[i], prev = i ? poly[i-1] : poly.back(); P d{1 + (ll)sqrt(ret.first), 0};
}
bool side = s.cross(e, cur) < 0; while (v[j].y <= p.y - d.x) S.erase(v[j++]);
if (side != (s.cross(e, prev) < 0)) auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d);
res.push_back(lineInter(s, e, cur, prev).second); for (; lo != hi; ++lo)
if (side) LineHullIntersection.h ret = min(ret, {(*lo - p).dist2(), {*lo, p}});
res.push_back(cur); Description: Line-convex polygon intersection. The polygon must be ccw S.insert(p);
} and have no collinear points. lineHull(line, poly) returns a pair describing }
return res; the intersection of a line with the polygon: • (−1, −1) if no collision, • (i, −1) return ret.second;
} if touching the corner i, • (i, i) if along side (i, i + 1), • (i, j) if crossing sides }
(i, i + 1) and (j, j + 1). In the last case, if a corner i is crossed, this is treated
as happening on side (i, i + 1). The points are returned in the same order as
ConvexHull.h the line hits the polygon. extrVertex returns the point of a hull with the
kdTree.h
Description: KD-tree (2d, can be extended to 3d)
Description: max projection onto a line.
"Point.h" bac5b0, 63 lines
Returns a vector of the points of the convex hull in counter- Time: O (log n)
clockwise order. Points on the edge of the hull between two "Point.h" 7cf45b, 39 lines typedef long long T;
other points are not considered part of the hull. typedef Point<T> P;
#define cmp(i,j) sgn(dir.perp().cross(poly[(i)%n]-poly[(j)%n]))
Time: O (n log n) #define extr(i) cmp(i + 1, i) >= 0 && cmp(i, i - 1 + n) < 0
const T INF = numeric_limits<T>::max();
"Point.h" 310954, 13 lines
template <class P> int extrVertex(vector<P>& poly, P dir) {
typedef Point<ll> P; bool on_x(const P& a, const P& b) { return a.x < b.x; }
int n = sz(poly), lo = 0, hi = n;
vector<P> convexHull(vector<P> pts) { bool on_y(const P& a, const P& b) { return a.y < b.y; }
if (extr(0)) return 0;
if (sz(pts) <= 1) return pts; while (lo + 1 < hi) {
sort(all(pts)); struct Node {
int m = (lo + hi) / 2;
vector<P> h(sz(pts)+1); P pt; // i f t h i s i s a leaf , the single point in i t
if (extr(m)) return m;
int s = 0, t = 0; T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; // bounds
int ls = cmp(lo + 1, lo), ms = cmp(m + 1, m);
for (int it = 2; it--; s = --t, reverse(all(pts))) Node *first = 0, *second = 0;
(ls < ms || (ls == ms && ls == cmp(lo, m)) ? hi : lo) = m;
for (P p : pts) { }
while (t >= s + 2 && h[t-2].cross(h[t-1], p) <= 0) t--; T distance(const P& p) { // min squared distance to a point
return lo;
h[t++] = p; T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x);
}
} T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y);
return {h.begin(), h.begin() + t - (t == 2 && h[0] == h[1])}; return (P(x,y) - p).dist2();
#define cmpL(i) sgn(a.cross(poly[i], b))
} }
template <class P>
array<int, 2> lineHull(P a, P b, vector<P>& poly) {
Node(vector<P>&& vp) : pt(vp[0]) {
int endA = extrVertex(poly, (a - b).perp());
HullDiameter.h int endB = extrVertex(poly, (b - a).perp());
for (P p : vp) {
Description: Returns the two points with max distance on a convex hull if (cmpL(endA) < 0 || cmpL(endB) > 0)
x0 = min(x0, p.x); x1 = max(x1, p.x);
(ccw, no duplicate/collinear points). return {-1, -1};
y0 = min(y0, p.y); y1 = max(y1, p.y);
"Point.h" c571b8, 12 lines }
array<int, 2> res;
typedef Point<ll> P; if (vp.size() > 1) {
rep(i,0,2) {
array<P, 2> hullDiameter(vector<P> S) { // s p l i t on x i f width >= height (not ideal . . . )
int lo = endB, hi = endA, n = sz(poly);
int n = sz(S), j = n < 2 ? 0 : 1; sort(all(vp), x1 - x0 >= y1 - y0 ? on_x : on_y);
while ((lo + 1) % n != hi) {
pair<ll, array<P, 2>> res({0, {S[0], S[0]}}); // divide by taking h a l f the array for each child (not
int m = ((lo + hi + (lo < hi ? 0 : n)) / 2) % n;
rep(i,0,j) // best performance with many duplicates in the middle)
(cmpL(m) == cmpL(endB) ? lo : hi) = m;
for (;; j = (j + 1) % n) { int half = sz(vp)/2;
}
res = max(res, {(S[i] - S[j]).dist2(), {S[i], S[j]}}); first = new Node({vp.begin(), vp.begin() + half});
res[i] = (lo + !cmpL(hi)) % n;
if ((S[(j + 1) % n] - S[j]).cross(S[i + 1] - S[i]) >= 0) second = new Node({vp.begin() + half, vp.end()});
swap(endA, endB);
break; }
}
} }
if (res[0] == res[1]) return {res[0], -1};
return res.second; };
if (!cmpL(res[0]) && !cmpL(res[1]))
} switch ((res[0] - res[1] + sz(poly) + 1) % sz(poly)) {
struct KDTree {
case 0: return {res[0], res[0]};
Node* root;
case 2: return {res[1], res[1]};
PointInsideHull.h }
KDTree(const vector<P>& vp) : root(new Node({all(vp)})) {}
Description: Determine whether a point t lies inside a convex hull (CCW
return res;
order, with no collinear points). Returns true if point lies within the hull. If pair<T, P> search(Node *node, const P& p) {
}
strict is true, points on the boundary aren’t included. if (!node->first) {
KTH FastDelaunay PolyhedronVolume Point3D 3dHull 20
// uncomment i f we should not find the point i t s e l f : if (sz(s) == 2) return { a, a->r() }; template<class T> struct Point3D {
// i f (p == node−>pt ) return {INF, P()}; splice(a->r(), b); typedef Point3D P;
return make_pair((p - node->pt).dist2(), node->pt); auto side = s[0].cross(s[1], s[2]); typedef const P& R;
} Q c = side ? connect(b, a) : 0; T x, y, z;
return {side < 0 ? c->r() : a, side < 0 ? c : b->r() }; explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {}
Node *f = node->first, *s = node->second; } bool operator<(R p) const {
T bfirst = f->distance(p), bsec = s->distance(p); return tie(x, y, z) < tie(p.x, p.y, p.z); }
if (bfirst > bsec) swap(bsec, bfirst), swap(f, s); #define H(e) e->F(), e->p bool operator==(R p) const {
#define valid(e) (e->F().cross(H(base)) > 0) return tie(x, y, z) == tie(p.x, p.y, p.z); }
// search c l o s e s t side f i r s t , other side i f needed Q A, B, ra, rb; P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); }
auto best = search(f, p); int half = sz(s) / 2; P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); }
if (bsec < best.first) tie(ra, A) = rec({all(s) - half}); P operator*(T d) const { return P(x*d, y*d, z*d); }
best = min(best, search(s, p)); tie(B, rb) = rec({sz(s) - half + all(s)}); P operator/(T d) const { return P(x/d, y/d, z/d); }
return best; while ((B->p.cross(H(A)) < 0 && (A = A->next())) || T dot(R p) const { return x*p.x + y*p.y + z*p.z; }
} (A->p.cross(H(B)) > 0 && (B = B->r()->o))); P cross(R p) const {
Q base = connect(B->r(), A); return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x);
// find nearest point to a point , and i t s squared distance if (A->p == ra->p) ra = base->r(); }
// ( requires an arbitrary operator< for Point) if (B->p == rb->p) rb = base; T dist2() const { return x*x + y*y + z*z; }
pair<T, P> nearest(const P& p) { double dist() const { return sqrt((double)dist2()); }
return search(root, p); #define DEL(e, init, dir) Q e = init->dir; if (valid(e)) \ //Azimuthal angle ( longitude ) to x−axis in interval [−pi , pi ]
} while (circ(e->dir->F(), H(base), e->F())) { \ double phi() const { return atan2(y, x); }
}; Q t = e->dir; \ //Zenith angle ( l a t i t u d e ) to the z−axis in interval [0 , pi ]
splice(e, e->prev()); \ double theta() const { return atan2(sqrt(x*x+y*y),z); }
FastDelaunay.h splice(e->r(), e->r()->prev()); \ P unit() const { return *this/(T)dist(); } //makes d i s t ()=1
Description: Fast Delaunay triangulation. Each circumcircle contains none e = t; \ //returns unit vector normal to ∗ t h i s and p
of the input points. There must be no duplicate points. If all points are on a } P normal(P p) const { return cross(p).unit(); }
line, no triangles will be returned. Should work for doubles as well, though for (;;) { //returns point rotated ’ angle ’ radians ccw around axis
there may be precision issues in ’circ’. Returns triangles in order {t[0][0], DEL(LC, base->r(), o); DEL(RC, base, prev()); P rotate(double angle, P axis) const {
t[0][1], t[0][2], t[1][0], . . . }, all counter-clockwise. if (!valid(LC) && !valid(RC)) break; double s = sin(angle), c = cos(angle); P u = axis.unit();
Time: O (n log n) if (!valid(LC) || (valid(RC) && circ(H(RC), H(LC)))) return u*dot(u)*(1-c) + (*this)*c - cross(u)*s;
"Point.h" bf87ec, 88 lines
base = connect(RC, base->r()); }
else };
typedef Point<ll> P; base = connect(base->r(), LC->r());
typedef struct Quad* Q; }
typedef __int128_t lll; // (can be l l i f coords are < 2e4) 3dHull.h
return { ra, rb }; Description: Computes all faces of the 3-dimension hull of a point set. *No
P arb(LLONG_MAX,LLONG_MAX); // not equal to any other point } four points must be coplanar*, or else random results will be returned. All
struct Quad { faces will point
 outwards.
vector<P> triangulate(vector<P> pts) { Time: O n2
bool mark; Q o, rot; P p; sort(all(pts)); assert(unique(all(pts)) == pts.end());
P F() { return r()->p; } "Point3D.h" 5b45fc, 49 lines
if (sz(pts) < 2) return {};
Q r() { return rot->rot; } Q e = rec(pts).first; typedef Point3D<double> P3;
Q prev() { return rot->o->rot; } vector<Q> q = {e};
Q next() { return r()->prev(); } int qi = 0; struct PR {
}; while (e->o->F().cross(e->F(), e->p) < 0) e = e->o; void ins(int x) { (a == -1 ? a : b) = x; }
#define ADD { Q c = e; do { c->mark = 1; pts.push_back(c->p); \ void rem(int x) { (a == x ? a : b) = -1; }
bool circ(P p, P a, P b, P c) { // i s p in the circumcircle? q.push_back(c->r()); c = c->next(); } while (c != e); } int cnt() { return (a != -1) + (b != -1); }
lll p2 = p.dist2(), A = a.dist2()-p2, ADD; pts.clear(); int a, b;
B = b.dist2()-p2, C = c.dist2()-p2; while (qi < sz(q)) if (!(e = q[qi++])->mark) ADD; };
return p.cross(a,b)*C + p.cross(b,c)*A + p.cross(c,a)*B > 0; return pts;
} } struct F { P3 q; int a, b, c; };
Q makeEdge(P orig, P dest) {
Q q[] = {new Quad{0,0,0,orig}, new Quad{0,0,0,arb}, vector<F> hull3d(const vector<P3>& A) {
new Quad{0,0,0,dest}, new Quad{0,0,0,arb}}; assert(sz(A) >= 4);
rep(i,0,4) 8.5 3D vector<vector<PR>> E(sz(A), vector<PR>(sz(A), {-1, -1}));
q[i]->o = q[-i & 3], q[i]->rot = q[(i+1) & 3]; #define E(x,y) E[f.x][f.y]
return *q; PolyhedronVolume.h vector<F> FS;
} Description: Magic formula for the volume of a polyhedron. Faces should auto mf = [&](int i, int j, int k, int l) {
void splice(Q a, Q b) { point outwards. 3058c3, 6 lines
P3 q = (A[j] - A[i]).cross((A[k] - A[i]));
swap(a->o->rot->o, b->o->rot->o); swap(a->o, b->o); if (q.dot(A[l]) > q.dot(A[i]))
} template<class V, class L> q = q * -1;
Q connect(Q a, Q b) { double signedPolyVolume(const V& p, const L& trilist) { F f{q, i, j, k};
Q q = makeEdge(a->F(), b->p); double v = 0; E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i);
splice(q, a->next()); for (auto i : trilist) v += p[i.a].cross(p[i.b]).dot(p[i.c]); FS.push_back(f);
splice(q->r(), b); return v / 6; };
return q; } rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4)
} mf(i, j, k, 6 - i - j - k);
Point3D.h
pair<Q,Q> rec(const vector<P>& s) { Description: Class to handle points in 3D space. T can be e.g. double or rep(i,4,sz(A)) {
if (sz(s) <= 3) { long long. rep(j,0,sz(FS)) {
8058ae, 32 lines
Q a = makeEdge(s[0], s[1]), b = makeEdge(s[1], s.back()); F f = FS[j];
KTH sphericalDistance KMP Zfunc Manacher MinRotation SuffixArray SuffixTree 21
l = i; r = i + z[i]; ss[se[i]].pb(i);
if(f.q.dot(A[i]) > f.q.dot(A[f.a])) { }
}
E(a,b).rem(f.c); } for (int i = 0; i < cnt; ++i){
E(a,c).rem(f.b); } for (int j: ss[i]){
E(b,c).rem(f.a); return z; sp[fi[j]].pb(j);
swap(FS[j--], FS.back()); } }
FS.pop_back(); }
}
Manacher.h int ncnt = -1;
Description: For each position in a string, computes p[0][i] = half length for (int i = 0; i < cnt; ++i){
} int last = -1;
of longest even palindrome around pos i, p[1][i] = longest odd (half rounded
int nw = sz(FS); for (int j: sp[i]){
down).
rep(j,0,nw) {
Time: O (N ) if (se[j] != last){
F f = FS[j]; e7ad79, 13 lines last = se[j];
#define C(a, b, c) if (E(a,b).cnt() != 2) mf(f.a, f.b, i, f.c); template <class T> vector <int> manacher(const T &s){ ++ncnt;
C(a, b, c); C(a, c, b); C(b, c, a); // ex string: # a # a # b # c # }
// p value: 1 2 3 2 1 2 1 2 1 fi[j] = ncnt;
}
// minus 1: 0 1 2 1 0 1 0 1 0 }
} int R = -1, C = 0, rad = 0; }
for (F& it : FS) if ((A[it.b] - A[it.a]).cross( int _n = s.size(); ++k;
A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b); vector <int> p(_n, 0); cnt = ncnt + 1;
return FS; for (int i = 0; i < _n; ++i){ }
}; if (R >= i){ return fi;
rad = min(p[C * 2 - i], R - i); }
} vector <int> Kasai(string &s, const vector <int> &sa, const vector <int> &r){
sphericalDistance.h else rad = 0; vector <int> p(sa.size());
Description: Returns the shortest distance on the sphere with radius ra- while (i + rad < _n && i - rad >= 0 && s[i + rad] == s[i - rad]) p[0] = 0;
++rad; int q = 0;
dius between the points with azimuthal angles (longitude) f1 (φ1 ) and f2 (φ2 ) s.pb('@');
p[i] = rad;
from x axis and zenith angles (latitude) t1 (θ1 ) and t2 (θ2 ) from z axis (0 = if (i + rad - 1 >= R){ for (int i = 0; i < signed(s.length()) - 1; ++i){
north pole). All angles measured in radians. The algorithm starts by con- C = i; int j = sa[r[i] - 1];
verting the spherical coordinates to cartesian coordinates so if that is what R = i + rad - 1; while (s[i + q] == s[j + q]) ++q;
you have you can use only the two last rows. dx*radius is then the difference } p[r[i]] = q;
between the two points in the x direction and d*radius is the total distance } if (q) --q;
between the points. return p; }
611f07, 8 lines } s.pop_back();
return p;
double sphericalDistance(double f1, double t1, MinRotation.h }
double f2, double t2, double radius) { Description: Finds the lexicographically smallest rotation of a string.
double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1); Usage: rotate(v.begin(), v.begin()+minRotation(v), v.end());
double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1); Time: O (N ) d07a42, 8 lines
double dz = cos(t2) - cos(t1);
double d = sqrt(dx*dx + dy*dy + dz*dz); template <class T> int minRotation(const T&s){
int res = 0, _n = s.size();
return radius*2*asin(d/2); s += s;
} for (int i = 0; i < _n; ++i){
for (int j = 0; j < _n; ++j){
if (res + j == i || s[res 00j] < s[i + j]){
i += max(0, j - 1); break;
Strings (9) }
if (s[res + j] > s[i + j]){
res = i; break;
KMP.h }
Time: O (n) d4375c, 16 lines }
}
template <class T> vector <int> kmp(const T &s){
return res;
int _n = s.size();
}
vector <int> p(_n, 0);
for (int i = 1; i < _n; ++i){
int j = p[i - 1]; SuffixArray.h
while (j && s[j] != s[i]){ Time: O (n log n) 38db9f, 23 lines
j = p[j - 1]; template <class T> vector <int> SA(const T&s){
} int _n = s.size();
if (s[j] == s[i]) ++j; vector <int> fi(_n + 1, 0);
p[i] = j; vector <int> save;
} for (int i = 0; i < _n; ++i){
return p; save.pb(s[i]);
} }
sort(save.begin(), save.end());
Zfunc.h save.resize(unique(save.begin(), save.end()) - save.begin());
Description: z[x] computes the length of the longest common prefix of s[i:] for (int i = 0; i < _n; ++i){
and s, except z[0] = 0. (abacaba -> 0010301) fi[i] = upper_bound(save.begin(), save.end(), s[i]) - save.begin();
Time: O (n) 3ae526, 12 lines
}
int cnt = save.size() + 1;
template <class T> vector <int> ZFunc(const T &s){ ++_n;
int n = s.length(); int k = 0;
vector <int> z(n, 0);
while (cnt < _n){
for (int i = 1, l = 0, r = 0; i < n; ++i){
vector <int> sp[cnt];
if (i <= r){
vector <int> ss[cnt];
z[i] = min(z[i - l], r - l + 1);
vector <int> se(_n);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
for (int i = 0; i < _n; ++i){
if (i + z[i] > r){
se[i] = fi[(i + (1 << k)) % _n];
KTH Dinitz AhoCorasick IntervalContainer IntervalCover ConstantIntervals 22

AhoCorasick.h
Time: construction takes O (26N ), where N = sum of length of patterns.
Dinitz.h find(x) is O (N ), where N = length of x. findAll is O (N M ). f35677, 66 lines
3f02d8, 44 lines
struct Edge{ struct node{
int u, v; int link = -1, nxt[27], par, ch, go[27], val = -1, leaf = 0;
ll c; node(int par = -1,char ch = 'a') : par(par), ch(ch){
Edge() {} memset(nxt, -1, sizeof(nxt));
Edge(int u, int v, ll c){ memset(go, -1, sizeof(go));
this->u = u; }
this->v = v; };
this->c = c; struct Aho_Corasick{
} vector<node> aho;
}; void init(){
struct Dinic{ aho.clear();
const ll Inf = 1e17; aho.emplace_back(-1, 'a');
int n, sink, source; }
vector<vector<int>> adj; int add(string s, int val){
vector<Edge> s; int now = 0;
vector<int> h; for(char c : s){
vector<vector<int>::iterator> cur; if(aho[now].nxt[c - 'a' + 1] == -1){
void Assign(int n = 0){ aho[now].nxt[c - 'a' + 1] = aho.size();
this->n = n; aho.emplace_back(now, c);
adj.resize(n + 2); }
s.reserve(n + 2); now = aho[now].nxt[c - 'a' + 1];
cur.resize(n + 2); }
h.resize(n + 2); aho[now].leaf = val;
} return now;
void AddEdge(int u, int v, ll c){ }
s.emplace_back(u, v, c); int get_val(int u){
adj[u].emplace_back(s.size() - 1); if(u == 0) return 0;
s.emplace_back(v, u, 0); if(aho[u].val == -1){
adj[v].emplace_back(s.size() - 1); aho[u].val = aho[u].leaf + get_val(get_link(u));
} }
bool BFS(){
fill(h.begin(), h.end(), n + 2); }
return aho[u].val; IntervalContainer.h
Time: O (log N ) edce47, 23 lines
queue<int> q({sink}); int go(int v,int t){ set<pii>::iterator addInterval(set<pii>& is, int L, int R) {
h[sink] = 0; if(aho[v].go[t] == -1){ if (L == R) return is.end();
while(!q.empty()){ if(aho[v].nxt[t] != -1){
auto it = is.lower_bound({L, R}), before = it;
int c = q.front(); q.pop(); aho[v].go[t]=aho[v].nxt[t];
for(auto i : adj[c]) } while (it != is.end() && it->first <= R) {
if(h[s[i].v] == n + 2 && s[i ^ 1].c != 0){ else{ R = max(R, it->second);
h[s[i].v] = h[c] + 1; if(v == 0) aho[v].go[t] = 0; before = it = is.erase(it);
if(s[i].v == source) return true; else aho[v].go[t] = go(get_link(v), t); }
q.emplace(s[i].v); } if (it != is.begin() && (--it)->second >= L) {
} } L = min(L, it->first);
} return aho[v].go[t];
R = max(R, it->second);
return false; }
} int get_link(int v){ is.erase(it);
ll dfs(int v, ll flowin){ if(aho[v].link == -1){ }
if(v == sink) return flowin; if(aho[v].par == 0 || v == 0) aho[v].link = 0; return is.insert(before, {L,R});
ll flowout(0); else aho[v].link = go(get_link(aho[v].par), aho[v].ch - 'a' + 1); }
for(; cur[v] != adj[v].end(); ++cur[v]){ }
int i = *cur[v]; return aho[v].link; void removeInterval(set<pii>& is, int L, int R) {
if(s[i].c == 0 | h[s[i].v] + 1 != h[v]) continue; }
if (L == R) return;
ll q = dfs(s[i].v, min(flowin, s[i].c)); int get(string s){
int now = 0; auto it = addInterval(is, L, R);
flowout += q; int res = 0; auto r2 = it->second;
if(flowin != Inf) flowin -= q; for(char c : s){ if (it->first == L) is.erase(it);
s[i].c -= q; now = go(now, c - 'a' + 1); else (int&)it->second = L;
s[i ^ 1].c += q; res += get_val(now); if (R != r2) is.emplace(R, r2);
if(flowin == 0) break; } }
} return res;
return flowout; }
} }; IntervalCover.h
ll BlockFlow(){ Description: Compute indices of smallest set of intervals covering another
for(int i = 1; i <= n; ++i) cur[i] = adj[i].begin(); interval. Intervals should be [inclusive, exclusive). To support [inclusive,
return dfs(source, Inf);
inclusive], change (A) to add || R.empty(). Returns empty set on failure
}
ll MaxFlow(int s, int t){ (or if G is empty).
sink = t; Time: O (N log N ) 9e9d8d, 19 lines
source = s;
ll Flow(0); template<class T>
while(BFS()) Flow += BlockFlow(); vi cover(pair<T, T> G, vector<pair<T, T>> I) {
return Flow; vi S(sz(I)), R;
} iota(all(S), 0);
}; sort(all(S), [&](int a, int b) { return I[a] < I[b]; });
T cur = G.first;
int at = 0;
KTH TernarySearch LIS KnuthDP DivideAndConquerDP FastMod FastInput BumpAllocator ConstantIntervals 23
while (cur < G.second) { // (A) Description: When doing DP on intervals: a[i][j] = mini<k<j (a[i][k] + if (i & 1 << b) D[i] += D[iˆ(1 << b)];
pair<T, int> mx = make_pair(cur, -1); a[k][j]) + f (i, j), where the (minimal) optimal k increases with both i computes all sums of subsets.
while (at < sz(I) && I[S[at]].first <= cur) { and j, one can solve intervals in increasing order of length, and search
mx = max(mx, make_pair(I[S[at]].second, S[at])); k = p[i][j] for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This is
at++; known as Knuth DP. Sufficient criteria for this are if f (b, c) ≤ f (a, d) and 10.5.2 Pragmas
} f (a, c) + f (b, d) ≤ f (a, d) + f (b, c) for all a ≤ b ≤ c ≤ d. Consider also:
if (mx.second == -1) return {}; LineContainer(ch. Data structures), monotone queues, ternary search. • #pragma GCC optimize ("Ofast") will make GCC
cur = mx.first; Time: O N 2
R.push_back(mx.second); auto-vectorize loops and optimizes floating points better.
}
return R; DivideAndConquerDP.h • #pragma GCC target ("avx2") can double performance of
} Description: Given a[i] = minlo(i)≤k<hi(i) (f (i, k)) where the (minimal) vectorized code, but causes crashes on old machines.
optimal k increases with i, computes a[i] for i = L..R − 1.
Time: O ((N + (hi − lo)) log N ) d38d2b, 18 lines • #pragma GCC optimize ("trapv") kills the program on integer
ConstantIntervals.h struct DP { // Modify at w i l l : overflows (but is really slow).
Description: Split a monotone function on [from, to) into a minimal set of int lo(int ind) { return 0; }
int hi(int ind) { return ind; }
half-open intervals on which it has the same value. Runs a callback g for
ll f(int ind, int k) { return dp[ind][k]; } FastMod.h
each such interval. Description: Compute a%b about 5 times faster than usual, where b is
Usage: constantIntervals(0, sz(v), [&](int x){return v[x];}, void store(int ind, int k, ll v) { res[ind] = pii(k, v); }
constant but not known at compile time. Returns a value congruent to a
[&](int lo, int hi, T val){...}); (mod b) in the range [0, 2b).
Time: O k log n void rec(int L, int R, int LO, int HI) { 751a02, 8 lines
k 753a4c, 19 lines if (L >= R) return; typedef unsigned long long ull;
template<class F, class G, class T> int mid = (L + R) >> 1; struct FastMod {
void rec(int from, int to, F& f, G& g, int& i, T& p, T q) { pair<ll, int> best(LLONG_MAX, LO); ull b, m;
if (p == q) return; rep(k, max(LO,lo(mid)), min(HI,hi(mid))) FastMod(ull b) : b(b), m(-1ULL / b) {}
if (from == to) { best = min(best, make_pair(f(mid, k), k)); ull reduce(ull a) { // a % b + (0 or b)
g(i, to, p); store(mid, best.second, best.first); return a - (ull)((__uint128_t(m) * a) >> 64) * b;
i = to; p = q; rec(L, mid, LO, best.second+1); }
} else { rec(mid+1, R, best.second, HI); };
int mid = (from + to) >> 1; }
rec(from, mid, f, g, i, p, f(mid)); void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); }
rec(mid+1, to, f, g, i, p, q); }; FastInput.h
} Description: Read an integer from stdin. Usage requires your program to
} pipe in input from file.
template<class F, class G> Usage: ./a.out < input.txt
void constantIntervals(int from, int to, F f, G g) {
10.4 Debugging tricks Time: About 5x as fast as cin/scanf. 7b3c70, 17 lines
if (to <= from) return;
int i = from; auto p = f(i), q = f(to-1); • signal(SIGSEGV, [](int) { _Exit(0); }); inline char gc() { // l i k e getchar ()
rec(from, to-1, f, g, i, p, q); static char buf[1 << 16];
converts segfaults into Wrong Answers. Similarly one can static size_t bc, be;
g(i, to, q);
} catch SIGABRT (assertion failures) and SIGFPE (zero if (bc >= be) {
buf[0] = 0, bc = 0;
divisions). _GLIBCXX_DEBUG failures generate SIGABRT
10.2 Misc. algorithms (or SIGSEGV on gcc 5.4.0 apparently). }
be = fread(buf, 1, sizeof(buf), stdin);

return buf[bc++]; // returns 0 on EOF


TernarySearch.h • feenableexcept(29); kills the program on NaNs (1), }
Description: Find the smallest i in [a, b] that maximizes f (i), assuming 0-divs (4), infinities (8) and denormals (16). int readInt() {
that f (a) < . . . < f (i) ≥ · · · ≥ f (b). To reverse which of the sides allows
non-strict inequalities, change the < marked with (A) to <=, and reverse int a, c;
while ((a = gc()) < 40);
the loop at (B). To minimize f , change it to >, also at (B).
Usage: int ind = ternSearch(0,n-1,[&](int i){return a[i];});
10.5 Optimization tricks if (a == ’-’) return -readInt();
Time: O (log(b − a)) while ((c = gc()) >= 48) a = a * 10 + c - 480;
9155b4, 11 lines
__builtin_ia32_ldmxcsr(40896); disables denormals return a - 48;
template<class F> }
int ternSearch(int a, int b, F f) {
(which make floats 20x slower near their minimum value).
assert(a <= b);
while (b - a >= 5) { 10.5.1 Bit hacks BumpAllocator.h
int mid = (a + b) / 2; Description: When you need to dynamically allocate many objects and
if (f(mid) < f(mid+1)) a = mid; // (A) don’t care about freeing them. ”new X” otherwise has an overhead of some-
• x & -x is the least bit in x. thing like 0.05us + 16 bytes per allocation.
else b = mid+1; 745db2, 8 lines
} // Either g l o b a l l y or in a single class :
rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B) • for (int x = m; x; ) { --x &= m; ... } loops
static char buf[450 << 20];
return a; over all subset masks of m (except m itself). void* operator new(size_t s) {
} static size_t i = sizeof buf;
10.3 Dynamic programming • c = x&-x, r = x+c; (((rˆx) >> 2)/c) | r is the assert(s < i);
next number after x with the same number of bits set. return (void*)&buf[i -= s];
}
KnuthDP.h • rep(b,0,K) rep(i,0,(1 << K)) void operator delete(void*) {}
KTH SmallPtr BumpAllocatorSTL SIMD 24
SmallPtr.h mi one() { return _mm256_set1_epi32(-1); } vector <pii> generate_connected_graph(int _n, int _m, bool ring = 0, bool
loop = 0){
Description: A 32-bit pointer that points into BumpAllocator memory. bool all_zero(mi m) { return _mm256_testz_si256(m, m); }
vector <pii> edge = generate_tree(_n);
"BumpAllocator.h" 2dd6c9, 10 lines bool all_one(mi m) { return _mm256_testc_si256(m, one()); } map <pii, bool> mp;
template<class T> struct ptr { int maxx = _n * (_n - 1) / 2;
unsigned ind; ll example_filteredDotProduct(int n, short* a, short* b) { if (!loop) for (auto i: edge) mp[{i.fi, i.se}] = mp[{i.se, i.fi}] = 1;
ptr(T* p = 0) : ind(p ? unsigned((char*)p - buf) : 0) { int i = 0; ll r = 0; if (_m > maxx - _n + 1){
mi zero = _mm256_setzero_si256(), acc = zero; vector <pii> p;
assert(ind < sizeof buf);
while (i + 16 <= n) { for (int i = 1; i < _n; ++i){
} for (int j = i + 1 - ring; j <= _n; ++j){
T& operator*() const { return *(T*)(buf + ind); } mi va = L(a[i]), vb = L(b[i]); i += 16;
if (!loop && mp[{i, j}]) continue;
T* operator->() const { return &**this; } va = _mm256_and_si256(_mm256_cmpgt_epi16(vb, va), va); p.pb({i, j});
T& operator[](int a) const { return (&**this)[a]; } mi vp = _mm256_madd_epi16(va, vb); if (rd(0, 1)) swap(p.back().fi, p.back().se);
explicit operator bool() const { return ind; } acc = _mm256_add_epi64(_mm256_unpacklo_epi32(vp, zero), }
}; _mm256_add_epi64(acc, _mm256_unpackhi_epi32(vp, zero))); }
} while (_m > _n - 1){
union {ll v[4]; mi m;} u; u.m = acc; rep(i,0,4) r += u.v[i]; int k = rd(0, p.size() - 1);
BumpAllocatorSTL.h edge.pb(p[k]);
for (;i<n;++i) if (a[i] < b[i]) r += a[i]*b[i]; // <− equiv swap(p.back(), p[k]);
Description: BumpAllocator for STL containers. return r; p.pop_back(); --_m;
Usage: vector<vector<int, small<int>>> ed(N); bb66d4, 14 lines } }
char buf[450 << 20] alignas(16); return edge;
AAAGrader.cpp }
size_t buf_ind = sizeof buf; else{
Description: Grader to check if the solution is wrong or not bb66d4, 14 lines
while (_m > _n - 1){
template<class T> struct small { #include <bits/stdc++.h> int u = rd(1, _n), v;
typedef T value_type; #define pb push_back if (ring) v = rd(1, _n);
small() {} #define fi first else{
#define se second v = rd(1, _n - 1);
template<class U> small(const U&) {}
#define faster ios_base::sync_with_stdio(0); cin.tie(0); if (v >= u) ++v;
T* allocate(size_t n) { #include <conio.h> }
buf_ind -= n * sizeof(T); #define taskname "" if (!loop){
buf_ind &= 0 - alignof(T); using namespace std; if (mp[{u, v}]) continue;
return (T*)(buf + buf_ind); using ll = long long; mp[{u, v}] = mp[{v, u}] = 1;
} using pii = pair <int, int>; }
void deallocate(T*, size_t) {} mt19937_64 Rand(chrono::steady_clock::now().time_since_epoch().count()); edge.pb({u, v}); --_m;
const int maxN = 1e5 + 1; }
};
inline int rd(int l, int r){ return edge;
return l + Rand() % (r - l + 1); }
SIMD.h } }
void clear_file(bool x, bool y, bool z){ #define CHECKE
Description: Cheat sheet of SSE/AVX intrinsics, for doing arithmetic if (x){ bool checker(){
on several numbers at once. Can provide a constant factor improvement ofstream inp(taskname ".inp"); #ifdef CHECKER
of about 4, orthogonal to loop unrolling. Operations follow the pat- inp.close(); ifstream inp(taskname ".inp"); /// ///
tern " mm(256)? name (si(128|256)|epi(8|16|32|64)|pd|ps)". Not all } ifstream out(taskname ".out"); /// ///
are described here; grep for mm in /usr/lib/gcc/*/4.9/include/ for if (y){ ifstream ans(taskname ".ans"); /// ///
more. If AVX is unsupported, try 128-bit operations, ”emmintrin.h” and ofstream out(taskname ".out"); inp.close(); /// ///
#define SSE and MMX before including it. For aligned memory use out.close(); out.close(); /// ///
} ans.close(); /// ///
mm malloc(size, 32) or int buf[N] alignas(32), but prefer loadu/s- if (z){ #else
toreu. ofstream ans(taskname ".ans");
551b82, 43 lines return system("fc " taskname ".out " taskname ".ans") == 0;
ans.close(); #endif
#pragma GCC target ("avx2") // or sse4 .1 } }
#include "immintrin.h" cerr << "Clearing Completed!"; void generate_test(){
getch(); ofstream inp(taskname".inp");
typedef __m256i mi; exit(0); inp.close();
#define L(x) _mm256_loadu_si256((mi*)&(x)) } }
int christianopenaldovic, messiuuuuu; void Init(int tt){
// High−l e v e l / s p e c i f i c methods : void checktime(){ //clear_file(1, 1, 1); // inp out ans
ifstream timeout("timeout.txt"); generate_test();
// load (u)? si256 , store (u)? si256 , setzero si256 , mm malloc int d; timeout >> d; system(taskname ".exe");
// blendv ( epi8 | ps | pd) ( z?y : x) , movemask epi8 ( h i b i t s of bytes ) timeout.close(); system(taskname "brute.exe");
// i32gather epi32 (addr , x , 4) : map addr [ ] over 32−b parts of x christianopenaldovic = max(christianopenaldovic, d); if (!checker()){
// sad epu8 : sum of absolute differences of u8, outputs 4xi64 messiuuuuu += d; cerr << "WRONG ANSWER ON TEST: " << tt << "\n";
// maddubs epi16 : dot product of unsigned i7 ’ s , outputs 16xi15 cerr << "Time elapsed: " << d << "ms\n"; while (getch() != 27){}
// madd epi16 : dot product of signed i16 ’ s , outputs 8xi32 cerr << "Max elapsed: " << christianopenaldovic << "ms\n"; exit(0);
// extractf128 si256 ( , i ) (256−>128) , cvtsi128 si32 (128−>lo32 ) cerr << "Total elapsed: " << messiuuuuu << "ms\n"; }
} checktime();
// permute2f128 si256(x , x ,1) swaps 128−b i t lanes vector <pii> generate_tree(int _n, bool is_sort = 0){ cerr << "CORRECT ANSWER ON TEST: " << tt << "\n";
// shuffle epi32 (x , 3∗64+2∗16+1∗4+0) == x for each lane vector <int> idx(_n); vector <pii> edge; }
// s h u f f l e e p i 8 (x , y) takes a vector instead of an imm iota(idx.begin(), idx.end(), 1); signed main(){
if (!is_sort) random_shuffle(idx.begin(), idx.end()); for (int tt = 1; ; ++tt){
// Methods that work with most data types (append e . g . epi32 ) : for (int i = 2; i <= _n; ++i){ Init(tt);
// set1 , blend ( i8?x : y) , add , adds ( sat . ) , mullo , sub , and/or , int u = rd(1, i - 1); }
// andnot , abs , min, max, sign (1 ,x) , cmp( gt | eq) , unpack( lo | hi ) edge.pb({idx[u - 1], idx[i - 1]}); }
if (!is_sort && rd(0, 1)) swap(edge.back().fi, edge.back().se);
}
int sumi32(mi m) { union {int v[8]; mi m;} u; u.m = m; return edge;
int ret = 0; rep(i,0,8) ret += u.v[i]; return ret; } }
mi zero() { return _mm256_setzero_si256(); }
KTH techniques 25

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 Wavelet Tree
Lovasz toggle Mini-max Sack
Matrix tree theorem Nim Dynamic Segment Tree
Maximal matching, general graphs Games on graphs
Hopcroft-Karp AAATemplate.cpp
Games on graphs with loops Description: Grader for C++
Hall’s marriage theorem Grundy numbers bb66d4, 14 lines
Graphical sequences Bipartite games without repetition #include <bits/stdc++.h>
Floyd-Warshall General games without repetition #define pb push_back
Euler cycles Alpha-beta pruning #define fi first
Flow networks Probability theory #define se second
* Augmenting paths #define faster ios_base::sync_with_stdio(0); cin.tie(0);
Optimization
* Edmonds-Karp Binary search
Bipartite matching using namespace std;
Ternary search using ll = long long;
Min. path cover Unimodality and convex functions using ld = long double;
Topological sorting Binary search on derivative using pii = pair <int, int>;
Strongly connected components Numerical methods mt19937_64 Rand(chrono::steady_clock::now().time_since_epoch().count());
2-SAT Numeric integration const int maxN = 1e5 + 1;
Cut vertices, cut-edges and biconnected components //const int Mod = 1e9 + 7;
Newton’s method //const int inf =
Edge coloring Root-finding with binary/ternary search int n;
* Trees Golden section search
Vertex coloring Matrices void Init(){
* Bipartite graphs (=> trees) Gaussian elimination
* 3^n (special case of set cover) Exponentiation by squaring }
Diameter and centroid Sorting
K’th shortest path #define debug
Radix sort #define taskname ""
Shortest cycle Geometry
Dynamic programming signed main(){
Coordinates and vectors faster
Knapsack
* Cross product if (fopen(taskname".inp", "r")){
Coin change freopen(taskname".inp", "r", stdin);
Longest common subsequence * Scalar product
Convex hull freopen(taskname".out", "w", stdout);
Longest increasing subsequence Polygon cut }
Number of paths in a dag int tt = 1;
Closest pair //cin >> tt;
Shortest path in a dag Coordinate-compression
Dynprog over intervals while (tt--){
Quadtrees Init();
Dynprog over subsets KD-trees }
Dynprog over probabilities All segment-segment intersection if (fopen("timeout.txt", "r")){
Dynprog over trees Sweeping ofstream timeout("timeout.txt");
3^n set cover Discretization (convert to events and sweep) timeout << signed(double(clock()) / CLOCKS_PER_SEC * 1000);
Divide and conquer timeout.close();
Angle sweeping #ifndef debug
Knuth optimization Line sweeping
Convex hull optimizations cerr << "Time elapsed: " << signed(double(clock()) / CLOCKS_PER_SEC
Discrete second derivatives * 1000) << "ms\n";
RMQ (sparse table a.k.a 2^k-jumps) Strings #endif // debug
Bitonic cycle Longest common substring }
Log partitioning (loop over most restricted) Palindrome subsequences }
Combinatorics

You might also like