Академический Документы
Профессиональный Документы
Культура Документы
Omogen Heap
Simon Lindholm, Johan Sannemo, Mårten Wiman
Runtime error: p
Have you tested all corner cases locally? sin(v + w) = sin v cos w + cos v sin w 4A = 2ef · sin θ = F tan θ = 4e2 f 2 − F 2
Any uninitialized variables?
cos(v + w) = cos v cos w − sin v sin w
Are you reading or writing outside the range of any vector?
Any assertions that might fail?
For cyclic quadrilateralspthe sum of opposite angles is 180◦ ,
Any possible division by 0? (mod 0 for example) ef = ac + bd, and A = (p − a)(p − b)(p − c)(p − d).
KTH 2
2.4.3 Spherical coordinates 2.7 Series First success distribution
z
x2 x3
r ex = 1 + x + + + . . . , (−∞ < x < ∞) The number of trials needed to get the first success in
2! 3!
y independent yes/no experiments, each wich yields success
x2 x3 x4 with probability p is Fs(p), 0 ≤ p ≤ 1.
ln(1 + x) = x − + − + . . . , (−1 < x ≤ 1)
x 2 3 4
p(k) = p(1 − p)k−1 , k = 1, 2, . . .
√ x x 2
2x 5x 3 4
1+x=1+ − + − + . . . , (−1 ≤ x ≤ 1)
2 8 32 128 1 2 1−p
x = r sin θ cos φ
p
r = xp 2 + y2 + z2 µ= ,σ =
x3
x 5
x 7 p p2
y = r sin θ sin φ θ = acos(z/ x2 + y 2 + z 2 ) sin x = x − + − + . . . , (−∞ < x < ∞)
3! 5! 7!
z = r cos θ φ = atan2(y, x) Poisson distribution
x2 x4 x6
cos x = 1 − + − + . . . , (−∞ < x < ∞)
2.5 Derivatives/Integrals 2! 4! 6! The number of events occurring in a fixed period of time t if
these events occur with a known average rate κ and
2.8 Probability theory independently of the time since the last event is
d 1 d 1 Po(λ), λ = tκ.
arcsin x = √ arccos x = − √ Let X be a discrete random variable with probability pX (x)
dx 1 − x2 dx 1 − x2
of assuming the valuePx. It will then have an expected value
d d 1 λk
tan x = 1 + tan2 x arctan x = (mean) µ = E(X) = x xpX (x) and P variance p(k) = e−λ , k = 0, 1, 2, . . .
dx dx 1 + x2 σ 2 = V (X) = E(X 2 ) − (E(X))2 = x (x − E(X))2 pX (x) k!
ln | cos ax| sin ax − ax cos ax
Z Z
tan ax = − x sin ax = where σ is the standard deviation. If X is instead
a a2 continuous it will have a probability density function fX (x) µ = λ, σ 2 = λ
Z √ Z ax
2 π e and the sums above will instead be integrals with pX (x)
e−x = erf(x) xeax dx = 2 (ax − 1)
2 a replaced by fX (x). 2.8.2 Continuous distributions
Expectation is linear: Uniform distribution
Integration by parts:
E(aX + bY ) = aE(X) + bE(Y ) If the probability density function is constant between a and
Z b Z b
f (x)g(x)dx = [F (x)g(x)]ba − 0
F (x)g (x)dx b and 0 elsewhere it is U(a, b), a < b.
For independent X and Y ,
a a
1
2 2 b−a a<x<b
V (aX + bY ) = a V (X) + b V (Y ). f (x) =
2.6 Sums 0 otherwise
in state LazySegmentTree.h
int size(int x) { return -e[find(x)]; }
absorbing state in A. The probability for absorption
P Description: Segment tree with ability to add or set values of large intervals, int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
i ∈ A, when the initial state is j, is aij = pij + k∈G aik pkj . and compute max of intervals. Can be changed to other things. Use with a void join(int a, int b) {
a = find(a), b = find(b);
The expectedP time until absorption, when the initial state is bump allocator for better performance, and SmallPtr or implicit indices to
save memory. if (a == b) return;
i, is ti = 1 + k∈G pki tk . Usage: Node* tr = new Node(v, 0, sz(v)); if (e[a] > e[b]) swap(a, b);
Time: O (log N ). e[a] += e[b]; e[b] = a;
"../various/BumpAllocator.h" 50 lines }
Data structures (3) const int inf = 1e9;
};
KTH SubMatrix Matrix LineContainer Treap FenwickTree FenwickTree2d 4
SubMatrix.h // ( for doubles , use i n f = 1/.0 , div (a , b) = a/b) }
Description: Calculate submatrix sums quickly, given upper-left and lower- const ll inf = LLONG_MAX; }
right corners (half-open). ll div(ll a, ll b) { // floored division
Usage: SubMatrix<int> m(matrix); return a / b - ((a ˆ b) < 0 && a % b); } Node* ins(Node* t, Node* n, int pos) {
m.sum(0, 0, 2, 2); // top left 4 elements bool isect(iterator x, iterator y) { auto pa = split(t, pos);
Time: O N 2 + Q
13 lines
if (y == end()) { x->p = inf; return false; } return merge(merge(pa.first, n), pa.second);
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; }
template<class T> else x->p = div(y->m - x->m, x->k - y->k);
struct SubMatrix { return x->p >= y->p; // Example application : move the range [ l , r ) to index k
vector<vector<T>> p; } void move(Node*& t, int l, int r, int k) {
SubMatrix(vector<vector<T>>& v) { void add(ll k, ll m) { Node *a, *b, *c;
int R = sz(v), C = sz(v[0]); auto z = insert({k, m, 0}), y = z++, x = y; tie(a,b) = split(t, l); tie(b,c) = split(b, r - l);
p.assign(R+1, vector<T>(C+1)); while (isect(y, z)) z = erase(z); if (k <= l) t = merge(ins(a, b, k), c);
rep(r,0,R) rep(c,0,C) if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); else t = merge(a, ins(c, b, k - r));
p[r+1][c+1] = v[r][c] + p[r][c+1] + p[r+1][c] - p[r][c]; while ((y = x) != begin() && (--x)->p >= y->p) }
} isect(x, erase(y));
T sum(int u, int l, int d, int r) { }
return p[d][r] - p[d][l] - p[u][r] + p[u][l]; ll query(ll x) { FenwickTree.h
} assert(!empty()); Description: Computes partial sums a[0] + a[1] + ... + a[pos - 1], and
}; Q = 1; auto l = *lower_bound({0,0,x}); Q = 0; updates single elements a[i], taking the difference between the old and new
return l.k * x + l.m; value.
} Time: Both operations are O (log N ).
Matrix.h };
22 lines
the form 2a b + 1, where the convolution result has size at most 2a . For other
primes/integers, use two different primes and combine with CRT. May return 5.1 Modular arithmetic
negative values.
Time: O (N log N ) ModularArithmetic.h
"ModPow.h" 38 lines
Description: Operators for modular arithmetic. You need to set mod to ModMulLL.h
const ll mod = (119 << 23) + 1, root = 3; // = 998244353 some number first and then you can use the structure. Description: Calculate a · b mod c (or ab mod c) for large c.
// For p < 2ˆ30 there i s also e . g . (5 << 25, 3) , (7 << 26, 3) , "euclid.h" 18 lines Time: O (64/bits · log b), where bits = 64 − k, if we want to deal with k-bit
// (479 << 21, 3) and (483 << 21, 5) . The l a s t two are > 10ˆ9. const ll mod = 17; // change to something e l s e numbers. 19 lines
struct Mod {
typedef vector<ll> vl; typedef unsigned long long ull;
ll x;
void ntt(ll* x, ll* temp, ll* roots, int N, int skip) { const int bits = 10;
Mod(ll xx) : x(xx) {}
if (N == 1) return; // i f a l l numbers are l e s s than 2ˆk , set b i t s = 64−k
Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
int n2 = N/2; const ull po = 1 << bits;
Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); }
ntt(x , temp, roots, n2, skip*2); ull mod_mul(ull a, ull b, ull &c) {
Mod operator*(Mod b) { return Mod((x * b.x) % mod); }
ntt(x+skip, temp, roots, n2, skip*2); ull x = a * (b & (po - 1)) % c;
Mod operator/(Mod b) { return *this * invert(b); }
rep(i,0,N) temp[i] = x[i*skip]; while ((b >>= bits) > 0) {
Mod invert(Mod a) {
rep(i,0,n2) { a = (a << bits) % c;
ll x, y, g = euclid(a.x, mod, x, y);
ll s = temp[2*i], t = temp[2*i+1] * roots[skip*i]; x += (a * (b & (po - 1))) % c;
assert(g == 1); return Mod((x + mod) % mod);
x[skip*i] = (s + t) % mod; x[skip*(i+n2)] = (s - t) % mod; }
}
} return x % c;
Mod operatorˆ(ll e) {
} }
if (!e) return Mod(1);
void ntt(vl& x, bool inv = false) { ull mod_pow(ull a, ull b, ull mod) {
Mod r = *this ˆ (e / 2); r = r * r;
ll e = modpow(root, (mod-1) / sz(x)); if (b == 0) return 1;
return e&1 ? *this * r : r;
if (inv) e = modpow(e, mod-2); ull res = mod_pow(a, b / 2, mod);
}
vl roots(sz(x), 1), temp = roots; res = mod_mul(res, res, mod);
};
rep(i,1,sz(x)) roots[i] = roots[i-1] * e % mod; if (b & 1) return mod_mul(res, a, mod);
ntt(&x[0], &temp[0], &roots[0], sz(x), 1); return res;
} ModInverse.h }
vl conv(vl a, vl b) { Description: Pre-computation of modular inverses. Assumes LIM ≤ mod
int s = sz(a) + sz(b) - 1; if (s <= 0) return {}; and that mod is a prime. 3 lines
int L = s > 1 ? 32 - __builtin_clz(s - 1) : 0, n = 1 << L;
if (s <= 200) { // ( factor 10 optimization for | a | , | b | = 10) const ll mod = 1000000007, LIM = 200000;
vl c(s); ll* inv = new ll[LIM] - 1; inv[1] = 1;
rep(i,0,sz(a)) rep(j,0,sz(b)) rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[mod % i] % mod; ModSqrt.h
Description: Tonelli-Shanks algorithm for modular square roots.
c[i + j] = (c[i + j] + a[i] * b[j]) % mod; Time: O log2 p worst case, often O (log p)
return c; ModPow.h 6 lines "ModPow.h" 30 lines
}
a.resize(n); ntt(a); const ll mod = 1000000007; // f a s t e r i f const ll sqrt(ll a, ll p) {
b.resize(n); ntt(b); ll modpow(ll a, ll e) { a %= p; if (a < 0) a += p;
vl c(n); ll d = modpow(n, mod-2); if (e == 0) return 1; if (a == 0) return 0;
rep(i,0,n) c[i] = a[i] * b[i] % mod * d % mod; ll x = modpow(a * a % mod, e >> 1); assert(modpow(a, (p-1)/2, p) == 1);
ntt(c, true); c.resize(s); return c; return e & 1 ? x * a % mod : x; if (p % 4 == 3) return modpow(a, (p+1)/4, p);
} } // aˆ(n+3)/8 or 2ˆ(n+3)/8 ∗ 2ˆ(n−1)/4 works i f p % 8 == 5
ll s = p - 1;
int r = 0;
FastSubsetTransform.h ModSum.h while (s % 2 == 0)
Description: Transform to a basis with fast convolutions of the form Description: Sums of mod’ed
Pto−1arithmetic progressions. ++r, s /= 2;
X modsum(to, c, k, m) = i=0 (ki + c)%m. divsum is similar but for ll n = 2; // find a non−square mod p
c[z] = a[x] · b[y], where ⊕ is one of AND, OR, XOR. The size floored division.
z=x⊕y while (modpow(n, (p - 1) / 2, p) != p - 1) ++n;
of a must be a power of two. Time: log(m), with a large constant. 19 lines ll x = modpow(a, (s + 1) / 2, p);
Time: O (N log N ) 16 lines ll b = modpow(a, s, p);
typedef unsigned long long ull;
ll g = modpow(n, s, p);
void FST(vi& a, bool inv) { ull sumsq(ull to) { return to / 2 * ((to-1) | 1); }
for (;;) {
for (int n = sz(a), step = 1; step < n; step *= 2) {
ll t = b;
for (int i = 0; i < n; i += 2 * step) rep(j,i,i+step) { ull divsum(ull to, ull c, ull k, ull m) {
int m = 0;
int &u = a[j], &v = a[j + step]; tie(u, v) = ull res = k / m * sumsq(to) + c / m * to;
for (; m < r; ++m) {
inv ? pii(v - u, u) : pii(v, u + v); // AND k %= m; c %= m;
if (t == 1) break;
inv ? pii(v, u - v) : pii(u + v, u); // OR if (k) {
t = t * t % p;
pii(u + v, u - v); // XOR ull to2 = (to * k + c) / m;
}
} res += to * to2;
if (m == 0) return x;
} res -= divsum(to2, m-1 - c, m, k) + to2;
ll gs = modpow(g, 1 << (r - m - 1), p);
if (inv) trav(x, a) x /= sz(a); // XOR only }
g = gs * gs % p;
} return res;
x = x * gs % p;
vi conv(vi a, vi b) { }
b = b * g % p;
FST(a, 0); FST(b, 0);
r = m;
rep(i,0,sz(a)) a[i] *= b[i]; ll modsum(ull to, ll c, ll k, ll m) {
}
FST(a, 1); return a; c = ((c % m) + m) % m;
}
} k = ((k % m) + m) % m;
KTH eratosthenes MillerRabin factor euclid Euclid phiFunction ContinuedFractions FracBinarySearch 9
5.2 Primality ull x = 2, y = 2, c = 1; phiFunction.h
for (; c==1; c = __gcd((y > x ? y - x : x - y), d)) { Description: Euler’s totient or Euler’s phi function is defined as φ(n) := #
x = f(x, d, has); of positive integers ≤ n that are coprime with n. The cototient is n − φ(n).
eratosthenes.h y = f(f(y, d, has), d, has); φ(1) = 1, p prime ⇒ φ(pk ) = (p − 1)pk−1 , m, n coprime ⇒ φ(mn) =
Description: Prime sieve for generating all primes up to a certain limit. } k k r then φ(n) = (p − 1)pk1 −1 ...(p − 1)pkr −1 .
isprime[i] is true iff i is a prime. φ(m)φ(n). Q If n = p1 1 p2 2 ...pk
r 1 1 r r
if (c != d) { φ(n) = n · p|n (1 − 1/p).
Time: lim=100’000’000 ≈ 0.8 s. Runs 30% faster if only odd indices are res.push_back(c); d /= c; P P
stored. 11 lines if (d != c) res.push_back(d); d|n φ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nφ(n)/2, n > 1
const int MAX_PR = 5000000; break; Euler’s thm: a, n coprime ⇒ aφ(n) ≡ 1 (mod n).
bitset<MAX_PR> isprime; } Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 (mod p) ∀a. 10 lines
vi eratosthenes_sieve(int lim) { }
} const int LIM = 5000000;
isprime.set(); isprime[0] = isprime[1] = 0; int phi[LIM];
for (int i = 4; i < lim; i += 2) isprime[i] = 0; return res;
for (int i = 3; i*i < lim; i += 2) if (isprime[i]) }
void init(int bits) {//how many b i t s do we use? void calculatePhi() {
for (int j = i*i; j < lim; j += i*2) isprime[j] = 0; rep(i,0,LIM) phi[i] = i&1 ? i : i/2;
vi pr; vi p = eratosthenes_sieve(1 << ((bits + 2) / 3));
pr.assign(all(p)); for(int i = 3; i < LIM; i += 2)
rep(i,2,lim) if (isprime[i]) pr.push_back(i); if(phi[i] == i)
return pr; }
for(int j = i; j < LIM; j += i)
} (phi[j] /= i) *= i-1;
}
MillerRabin.h 5.3 Divisibility
Description: Miller-Rabin primality probabilistic test. Probability of fail-
ing one iteration is at most 1/4. 15 iterations should be enough for 50-bit 5.4 Fractions
numbers. euclid.h
Time: 15 times the complexity of ab mod c. Description: Finds the Greatest Common Divisor to the integers a and b. ContinuedFractions.h
"ModMulLL.h" 16 lines Euclid also finds two integers x and y, such that ax + by = gcd(a, b). If a Description: Given N and a real number x ≥ 0, finds the closest rational
bool prime(ull p) { and b are coprime, then x is the inverse of a (mod b). 7 lines approximation p/q with p, q ≤ N . It will obey |p/q − x| ≤ 1/qN .
if (p == 2) return true;
ll gcd(ll a, ll b) { return __gcd(a, b); } For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . (pk /qk alternates
if (p == 1 || p % 2 == 0) return false; between > x and < x.) If x is rational, y eventually becomes ∞; if x is the
ull s = p - 1; root of a degree 2 polynomial the a’s eventually become cyclic.
while (s % 2 == 0) s /= 2; ll euclid(ll a, ll b, ll &x, ll &y) {
if (b) { ll d = euclid(b, a % b, y, x); Time: O (log N ) 21 lines
rep(i,0,15) {
ull a = rand() % (p - 1) + 1, tmp = s; return y -= a/b * x, d; } typedef double d; // for N ∼ 1e7 ; long double for N ∼ 1e9
ull mod = mod_pow(a, tmp, p); return x = 1, y = 0, a; pair<ll, ll> approximate(d x, ll N) {
while (tmp != p - 1 && mod != 1 && mod != p - 1) { } ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; d y = x;
mod = mod_mul(mod, mod, p); for (;;) {
tmp *= 2; ll lim = min(P ? (N-LP) / P : inf, Q ? (N-LQ) / Q : inf),
} Euclid.java a = (ll)floor(y), b = min(a, lim),
if (mod != p - 1 && tmp % 2 == 0) return false; Description: Finds {x, y, d} s.t. ax + by = d = gcd(a, b). 11 lines NP = b*P + LP, NQ = b*Q + LQ;
} static BigInteger[] euclid(BigInteger a, BigInteger b) { if (a > b) {
return true; BigInteger x = BigInteger.ONE, yy = x; // I f b > a/2, we have a semi−convergent that gives us a
} BigInteger y = BigInteger.ZERO, xx = y; // better approximation ; i f b = a/2, we ∗may∗ have one .
while (b.signum() != 0) { // Return {P, Q} here for a more canonical approximation .
BigInteger q = a.divide(b), t = b; return (abs(x - (d)NP / (d)NQ) < abs(x - (d)P / (d)Q)) ?
factor.h b = a.mod(b); a = t; make_pair(NP, NQ) : make_pair(P, Q);
Description: Pollard’s rho algorithm. It is a probabilistic factorisation al- }
t = xx; xx = x.subtract(q.multiply(xx)); x = t;
gorithm, whose expected time complexity is good. Before you start using it, if (abs(y = 1/(y - (d)a)) > 3*N) {
t = yy; yy = y.subtract(q.multiply(yy)); y = t;
run init(bits), where bits is the length of the numbers you use. Returns return {NP, NQ};
}
factors of the input without duplicates. }
return new BigInteger[]{x, y, a};
Time: Expected running time should be good enough for 50-bit numbers. LP = P; P = NP;
}
"ModMulLL.h", "MillerRabin.h", "eratosthenes.h" 35 lines LQ = Q; Q = NQ;
vector<ull> pr; }
ull f(ull a, ull n, ull &has) { 5.3.1 Bézout’s identity }
return (mod_mul(a, a, n) + has) % n;
} FracBinarySearch.h
vector<ull> factor(ull d) {
For a 6=, b 6= 0, then d = gcd(a, b) is the smallest positive
Description: Given f and N , finds the smallest fraction p/q ∈ [0, 1] such
vector<ull> res; integer for which there are integer solutions to that f (p/q) is true, and p, q ≤ N . You may want to throw an exception from
for (int i = 0; i < sz(pr) && pr[i]*pr[i] <= d; i++) f if it finds an exact solution, in which case N can be removed.
if (d % pr[i] == 0) { Usage: fracBS([](Frac f) { return f.p>=3*f.q; }, 10); // {1,3}
while (d % pr[i] == 0) d /= pr[i]; ax + by = d Time: O (log(N )) 24 lines
res.push_back(pr[i]);
} struct Frac { ll p, q; };
//d i s now a product of at most 2 primes .
if (d > 1) {
If (x, y) is one solution, then all solutions are given by template<class F>
if (prime(d)) Frac fracBS(F f, ll N) {
res.push_back(d); bool dir = 1, A = 1, B = 1;
else while (true) { kb ka Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to search (0 , N]
x+ ,y − , k∈Z
ull has = rand() % 2321 + 47; gcd(a, b) gcd(a, b) assert(!f(lo)); assert(f(hi));
KTH chinese IntPerm binomialModPrime multinomial 10
g
while (A || B) { 5.8 Estimates where X are the elements fixed by g (g.x = x).
ll adv = 0, step = 1; // move hi i f dir , e l s e lo
for (int si = 0; step; (step *= 2) >>= si) {
P
adv += step; d|n d = O(n log log n). If f (n) counts ”configurations” (of some sort) of length n, we
Frac mid{lo.p * adv + hi.p, lo.q * adv + hi.q};
The number of divisors of n is at most around 100 for can ignore rotational symmetry using G = Zn to get
if (abs(mid.p) > N || mid.q > N || dir == !f(mid)) {
adv -= step; si = 2; n < 5e4, 500 for n < 1e7, 2000 for n < 1e10, 200 000 for
} n−1
} n < 1e19. 1X 1X
hi.p += lo.p * adv; g(n) = f (gcd(n, k)) = f (k)φ(n/k).
hi.q += lo.q * adv;
n n
dir = !dir; Combinatorial (6) k=0 k|n
swap(lo, hi);
A = B; B = !!adv; 6.1 Permutations
}
return dir ? hi : lo; 6.2 Partitions and subsets
} 6.1.1 Factorial
n 123 4 5 6 7 8 9 10 6.2.1 Partition function
5.5 Chinese remainder theorem n! 1 2 6 24 120 720 5040 40320 362880 3628800
n 11 12 13 14 15 16 17 Number of ways of writing n as a sum of positive integers,
chinese.h n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14 disregarding the order of the summands.
Description: Chinese Remainder Theorem.
chinese(a, m, b, n) returns a number x, such that x ≡ a (mod m) and n 20 25 30 40 50 100 150 171 X
x ≡ b (mod n). For not coprime n, m, use chinese common. Note that all
numbers must be less than 231 if you have Z = unsigned long long.
n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL MAX p(0) = 1, p(n) = (−1)k+1 p(n − k(3k − 1)/2)
Time: log(m + n) k∈Z\{0}
"euclid.h" 13 lines
IntPerm.h
Description: Permutation -> integer conversion. (Not order preserving.)
template<class Z> Z chinese(Z a, Z m, Z b, Z n) { Time: O (n)
Z x, y; euclid(m, n, x, y); 6 lines √
Z ret = a * (y + m) % m * n + b * (x + n) % n * m; int permToInt(vi& v) { p(n) ∼ 0.145/n · exp(2.56 n)
if (ret >= m * n) ret -= m * n; int use = 0, i = 0, r = 0;
return ret; trav(x, v) r = r * ++i + __builtin_popcount(use & -(1 << x)),
} use |= 1 << x; // (note : minus, not ∼! ) n 0 1 2 3 4 5 6 7 8 9 20 50 100
return r; p(n) 1 1 2 3 5 7 11 15 22 30 627 ∼2e5 ∼2e8
template<class Z> Z chinese_common(Z a, Z m, Z b, Z n) { }
Z d = gcd(m, n);
if (((b -= a) %= n) < 0) b += n;
6.2.2 Binomials
if (b % d) return -1; // No solution 6.1.2 Cycles
return d * chinese(Z(0), m/d, b/d, n/d) + a; binomialModPrime.h
}
Let gS (n) be the number of n-permutations whose cycle Description: Lucas’ thm: Let n, m be non-negative integers and p a prime.
Write nQ= nk pk + ... + n1 p + n0 and m = mk pk + ... + m1 p + m0 . Then
lengths all belong to the set S. Then n
≡ k
i=0 mi
ni
(mod p). fact and invfact must hold pre-computed facto-
m
5.6 Pythagorean Triples ∞
! rials / inverse factorials, e.g. from ModInverse.h.
X xn X xn Time: O logp n
gS (n) = exp 10 lines
The Pythagorean triples are uniquely generated by n! n ll chooseModP(ll n, ll m, int p, vi& fact, vi& invfact) {
n=0 n∈S
ll c = 1;
a = k · (m2 − n2 ), b = k · (2mn), c = k · (m2 + n2 ), 6.1.3 Derangements
while (n || m) {
ll a = n % p, b = m % p;
if (a < b) return 0;
with m > n > 0, k > 0, m⊥n, and either m or n even. Permutations of a set such that none of the elements appear c = c * fact[a] % p * invfact[b] % p * invfact[a - b] % p;
n /= p; m /= p;
in their original position. }
return c;
5.7 Primes
n! }
D(n) = (n−1)(D(n−1)+D(n−2)) = nD(n−1)+(−1)n =
p = 962592769 is such that 221 | p − 1, which may be useful. e
For hashing use 970592641 (31-bit number), 31443539979727 multinomial.h k + · · · + k P
( ki )!
6.1.4 Burnside’s lemma Description: Computes
1 n
= .
(45-bit), 3006703054056749 (52-bit). There are 78498 primes k1 , k2 , . . . , kn k1 !k2 !...kn ! 6 lines
less than 1 000 000. Given a group G of symmetries and a set X, the number of ll multinomial(vi& v) {
ll c = 1, m = v.empty() ? 1 : v[0];
elements of X up to symmetry equals rep(i,1,sz(v)) rep(j,0,v[i])
Primitive roots exist modulo any prime power pa , except for c = c * ++m / (j+1);
p = 2, a > 2, and there are φ(φ(pa )) many. For p = 2, a > 2, 1 X g
|X |, return c;
the group Z×a is instead isomorphic to Z2 × Z2a−2 . |G| }
2 g∈G
KTH bellmanFord FloydWarshall TopoSort EulerWalk 11
6.3 General purpose numbers 6.3.5 Catalan numbers Description: Calculates all-pairs shortest path in a directed graph that
might have negative edge distances. Input is an distance matrix m, where
m[i][j] = inf if i and j are not adjacent. As output, m[i][j] is set to the
6.3.1 Stirling numbers of the first kind shortest distance between i and j, inf if no path, or -inf if the path goes
1 2n 2n 2n (2n)! through a negative-weight cycle.
Number of permutations on n items with k cycles. Cn = = − = Time: O N 3
n+1 n n n+1 (n + 1)!n! 12 lines
vector<bool> lfound(n, true); vi num, st; void at_most_one(const vi& li) { // ( optional )
KTH TreePower LCA CompressTree HLD 15
if (sz(li) <= 1) return; typedef vector<pii> vpi; HLD.h
int cur = ∼li[0]; typedef vector<vpi> graph; Description: Decomposes a tree into vertex disjoint heavy paths and light
rep(i,2,sz(li)) { const pii inf(1 << 29, -1); edges such that the path from any leaf to the root contains at most log(n)
int next = add_var(); light edges. The function of the HLD can be changed by modifying T, LOW
either(cur, ∼li[i]); struct LCA { and f. f is assumed to be associative and commutative.
either(cur, next); vi time; Usage: HLD hld(G);
either(∼li[i], next); vector<ll> dist; hld.update(index, value);
cur = ∼next; RMQ<pii> rmq; tie(value, lca) = hld.query(n1, n2);
} "../data-structures/SegmentTree.h" 93 lines
either(cur, ∼li[1]); LCA(graph& C) : time(sz(C), -99), dist(sz(C)), rmq(dfs(C)) {} typedef vector<pii> vpi;
}
vpi dfs(graph& C) { struct Node {
vi val, comp, z; int time = 0; vector<tuple<int, int, int, ll> > q(1); int d, par, val, chain = -1, pos = -1;
int dfs(int i) { vpi ret; };
int low = val[i] = ++time, x; z.push_back(i); int T = 0, v, p, d; ll di;
trav(e, gr[i]) if (!comp[e]) while (!q.empty()) { struct Chain {
low = min(low, val[e] ?: dfs(e)); tie(v, p, d, di) = q.back(); int par, val;
++time; q.pop_back(); vector<int> nodes;
if (low == val[i]) do { if (d) ret.emplace_back(d, p); Tree tree;
x = z.back(); z.pop_back(); time[v] = T++; };
comp[x] = time; dist[v] = di;
if (values[x>>1] == -1) trav(e, C[v]) if (e.first != p) struct HLD {
values[x>>1] = !(x&1); q.emplace_back(e.first, v, d+1, di + e.second); typedef int T;
} while (x != i); } const T LOW = -(1<<29);
return val[i] = low; return ret; void f(T& a, T b) { a = max(a, b); }
} }
vector<Node> V;
bool solve() { int query(int a, int b) { vector<Chain> C;
values.assign(N, -1); if (a == b) return a;
val.assign(2*N, 0); comp = val; a = time[a], b = time[b]; HLD(vector<vpi>& g) : V(sz(g)) {
rep(i,0,2*N) if (!comp[i]) dfs(i); return rmq.query(min(a, b), max(a, b)).second; dfs(0, -1, g, 0);
rep(i,0,N) if (comp[2*i] == comp[2*i+1]) return 0; } trav(c, C){
return 1; ll distance(int a, int b) { c.tree.init(sz(c.nodes), 0);
} int lca = query(a, b); for (int ni : c.nodes)
}; return dist[a] + dist[b] - 2 * dist[lca]; c.tree.update(V[ni].pos, V[ni].val);
} }
}; }
7.7 Trees
void update(int node, T val) {
Node& n = V[node]; n.val = val;
TreePower.h if (n.chain != -1) C[n.chain].tree.update(n.pos, val);
Description: Calculate power of two jumps in a tree. Assumes the root
CompressTree.h }
node points to itself.
Time: O (|V | log |V |) Description: Given a rooted tree and a subset S of nodes, compute the
14 lines int pard(Node& nod) {
minimal subtree that contains all the nodes by adding all (at most |S| − 1)
vector<vi> treeJump(vi& P){ pairwise LCA’s and compressing edges. Returns a list of (par, orig index) if (nod.par == -1) return -1;
int on = 1, d = 1; representing a tree rooted at 0. The root points to itself. return V[nod.chain == -1 ? nod.par : C[nod.chain].par].d;
while(on < sz(P)) on *= 2, d++; Time: O (|S| log |S|) }
vector<vi> jmp(d, P); "LCA.h" 20 lines
rep(i,1,d) rep(j,0,sz(P)) // query a l l ∗edges∗ between n1, n2
vpi compressTree(LCA& lca, const vi& subset) { pair<T, int> query(int i1, int i2) {
jmp[i][j] = jmp[i-1][jmp[i-1][j]];
static vi rev; rev.resize(sz(lca.dist)); T ans = LOW;
return jmp;
vi li = subset, &T = lca.time; while(i1 != i2) {
}
auto cmp = [&](int a, int b) { return T[a] < T[b]; }; Node n1 = V[i1], n2 = V[i2];
sort(all(li), cmp); if (n1.chain != -1 && n1.chain == n2.chain) {
int jmp(vector<vi>& tbl, int nod, int steps){
int m = sz(li)-1; int lo = n1.pos, hi = n2.pos;
rep(i,0,sz(tbl))
rep(i,0,m) { if (lo > hi) swap(lo, hi);
if(steps&(1<<i)) nod = tbl[i][nod];
int a = li[i], b = li[i+1]; f(ans, C[n1.chain].tree.query(lo, hi));
return nod;
li.push_back(lca.query(a, b)); i1 = i2 = C[n1.chain].nodes[hi];
}
} } else {
sort(all(li), cmp); if (pard(n1) < pard(n2))
LCA.h li.erase(unique(all(li)), li.end()); n1 = n2, swap(i1, i2);
Description: Lowest common ancestor. Finds the lowest common ancestor rep(i,0,sz(li)) rev[li[i]] = i; if (n1.chain == -1)
in a tree (with 0 as root). C should be an adjacency list of the tree, either vpi ret = {pii(0, li[0])}; f(ans, n1.val), i1 = n1.par;
directed or undirected. Can also find the distance between two nodes. rep(i,0,sz(li)-1) { else {
Usage: LCA lca(undirGraph); int a = li[i], b = li[i+1]; Chain& c = C[n1.chain];
lca.query(firstNode, secondNode); ret.emplace_back(rev[lca.query(a, b)], b); f(ans, n1.pos ? c.tree.query(n1.pos, sz(c.nodes))
lca.distance(firstNode, secondNode); } : c.tree.s[1]);
Time: O (|V | log |V | + Q) return ret; i1 = c.par;
"../data-structures/RMQ.h" 38 lines } }
KTH LinkCutTree MatrixTree Point lineDistance SegmentDistance 16
}
} }
void splay() {
Geometry (8)
return make_pair(ans, i1); for (push_flip(); p; ) {
} if (p->p) p->p->push_flip();
p->push_flip(); push_flip(); 8.1 Geometric primitives
// query a l l ∗nodes∗ between n1, n2 int c1 = up(), c2 = p->up();
pair<T, int> query2(int i1, int i2) { if (c2 == -1) p->rot(c1, 2);
pair<T, int> ans = query(i1, i2); else p->p->rot(c2, c1 != c2);
f(ans.first, V[ans.second].val); } Point.h
return ans; } Description: Class to handle points in the plane. T can be e.g. double or
} Node* first() { long long. (Avoid int.) 25 lines
push_flip(); template<class T>
pii dfs(int at, int par, vector<vpi>& g, int d) { return c[0] ? c[0]->first() : (splay(), this); struct Point {
V[at].d = d; V[at].par = par; } typedef Point P;
int sum = 1, ch, nod, sz; }; T x, y;
tuple<int,int,int> mx(-1,-1,-1); explicit Point(T x=0, T y=0) : x(x), y(y) {}
trav(e, g[at]){ struct LinkCut { bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); }
if (e.first == par) continue; vector<Node> node; bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); }
tie(sz, ch) = dfs(e.first, at, g, d+1); LinkCut(int N) : node(N) {} P operator+(P p) const { return P(x+p.x, y+p.y); }
V[e.first].val = e.second; P operator-(P p) const { return P(x-p.x, y-p.y); }
sum += sz; void link(int u, int v) { // add an edge (u, v) P operator*(T d) const { return P(x*d, y*d); }
mx = max(mx, make_tuple(sz, e.first, ch)); assert(!connected(u, v)); P operator/(T d) const { return P(x/d, y/d); }
} make_root(&node[u]); T dot(P p) const { return x*p.x + y*p.y; }
tie(sz, nod, ch) = mx; node[u].pp = &node[v]; T cross(P p) const { return x*p.y - y*p.x; }
if (2*sz < sum) return pii(sum, -1); } T cross(P a, P b) const { return (a-*this).cross(b-*this); }
if (ch == -1) { ch = sz(C); C.emplace_back(); } void cut(int u, int v) { // remove an edge (u, v) T dist2() const { return x*x + y*y; }
V[nod].pos = sz(C[ch].nodes); Node *x = &node[u], *top = &node[v]; double dist() const { return sqrt((double)dist2()); }
V[nod].chain = ch; make_root(top); x->splay(); // angle to x−axis in interval [−pi , pi ]
C[ch].par = at; assert(top == (x->pp ?: x->c[0])); double angle() const { return atan2(y, x); }
C[ch].nodes.push_back(nod); if (x->pp) x->pp = 0; P unit() const { return *this/dist(); } // makes d i s t ()=1
return pii(sum, ch); else { P perp() const { return P(-y, x); } // rotates +90 degrees
} x->c[0] = top->p = 0; P normal() const { return perp().unit(); }
}; x->fix(); // returns point rotated ’a ’ radians ccw around the origin
} P rotate(double a) const {
} return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
LinkCutTree.h bool connected(int u, int v) { // are u, v in the same tree? };
Description: Represents a forest of unrooted trees. You can add and re- Node* nu = access(&node[u])->first();
move edges (as long as the result is still a forest), and check whether two return nu == access(&node[v])->first();
nodes are in the same tree. }
Time: All operations take amortized O (log N ). 90 lines void make_root(Node* u) { lineDistance.h
access(u); Description:
struct Node { // Splay tree . Root ’ s pp contains tree ’ s parent .
Node *p = 0, *pp = 0, *c[2];
u->splay(); Returns the signed distance between point p and the line con-
bool flip = 0;
if(u->c[0]) { taining points a and b. Positive value on left side and negative res
Node() { c[0] = c[1] = 0; fix(); }
u->c[0]->p = 0; on right as seen from a towards b. a==b gives nan. P is sup- e p
void fix() {
u->c[0]->flip ˆ= 1; posed to be Point<T> or Point3D<T> where T is e.g. double
if (c[0]) c[0]->p = this;
u->c[0]->pp = u; or long long. It uses products in intermediate steps so watch
if (c[1]) c[1]->p = this;
u->c[0] = 0; out for overflow if using int or long long. Using Point3D will s
// (+ update sum of subtree elements etc . i f wanted)
u->fix(); always give a non-negative distance.
} "Point.h" 4 lines
}
} template<class P>
void push_flip() {
Node* access(Node* u) { double lineDist(const P& a, const P& b, const P& p) {
if (!flip) return;
u->splay(); return (double)(b-a).cross(p-a)/(b-a).dist();
flip = 0; swap(c[0], c[1]);
while (Node* pp = u->pp) { }
if (c[0]) c[0]->flip ˆ= 1;
pp->splay(); u->pp = 0;
if (c[1]) c[1]->flip ˆ= 1;
if (pp->c[1]) {
}
e res p
pp->c[1]->p = 0; pp->c[1]->pp = pp; }
int up() { return p ? p->c[1] == this : -1; } SegmentDistance.h
pp->c[1] = u; pp->fix(); u = pp;
void rot(int i, int b) { Description:
}
int h = i ˆ b; Returns the shortest distance between point p and the line
return u;
Node *x = c[i], *y = b == 2 ? x : x->c[h], *z = b ? y : x;
} segment from point s to e. s
if ((y->p = p)) p->c[up()] = y; Usage: Point<double> a, b(2,2), p(1,1);
};
c[i] = z->c[i ˆ 1]; bool onSegment = segDist(a,b,p) < 1e-10;
if (b < 2) { "Point.h" 6 lines
x->c[h] = y->c[h ˆ 1];
MatrixTree.h typedef Point<double> P;
z->c[h ˆ 1] = b ? x : this;
Description: To count the number of spanning trees in an undirected double segDist(P& s, P& e, P& p) {
}
graph G: create an N × N matrix mat, and for each edge (a, b) ∈ G, do if (s==e) return (p-s).dist();
y->c[i ˆ 1] = b ? this : x;
mat[a][a]++, mat[b][b]++, mat[a][b]--, mat[b][a]--. Remove the auto d = (e-s).dist2(), t = min(d,max(.0,(p-s).dot(e-s)));
fix(); x->fix(); y->fix();
last row and column, and take the determinant. return ((p-s)*d-(e-s)*t).dist()/d;
if (p) p->fix();
}
swap(pp, y->pp);
KTH SegmentIntersection SegmentIntersectionQ lineIntersection sideOf onSegment linearTransformation Angle CircleIntersection 17
SegmentIntersection.h lineIntersection.h Angle.h
Description: Description: Description: A class for ordering angles (as represented by int points and
If a unique intersetion point between the line segments going If a unique intersetion point of the lines going through s1,e1 a number of rotations around the origin). Useful for rotational sweeping.
from s1 to e1 and from s2 to e2 exists r1 is set to this point and s2,e2 exists r is set to this point and 1 is returned. If no Sometimes also represents points or vectors.
and 1 is returned. If no intersection point exists 0 is returned intersection point exists 0 is returned and if infinitely many Usage: vector<Angle> v = {w[0], w[0].t360() ...}; // sorted
and if infinitely many exists 2 is returned and r1 and r2 are e1 exists -1 is returned. If s1==e1 or s2==e2 -1 is returned. The
e2 r int j = 0; rep(i,0,n) { while (v[j] < v[i].t180()) ++j; }
set to the two ends of the common line. The wrong position e2 wrong position will be returned if P is Point<int> and the in- e1 s2 // sweeps j such that (j-i) represents the number of positively
will be returned if P is Point<int> and the intersection point r1 tersection point does not have integer coordinates. Products s1 oriented triangles with vertices at 0 and i 37 lines
does not have integer coordinates. Products of three coordi- s1 s2 of three coordinates are used in intermediate steps so watch
nates are used in intermediate steps so watch out for overflow out for overflow if using int or long long. struct Angle {
if using int or long long. Use segmentIntersectionQ to get just Usage: point<double> intersection; int x, y;
a true/false answer. if (1 == LineIntersection(s1,e1,s2,e2,intersection)) int t;
Usage: Point<double> intersection, dummy; cout << "intersection point at " << intersection << endl; Angle(int x, int y, int t=0) : x(x), y(y), t(t) {}
if (segmentIntersection(s1,e1,s2,e2,intersection,dummy)==1) "Point.h" 9 lines Angle operator-(Angle b) const { return {x-b.x, y-b.y, t}; }
cout << "segments intersect at " << intersection << endl; template<class P> int quad() const {
"Point.h" 27 lines int lineIntersection(const P& s1, const P& e1, const P& s2, assert(x || y);
const P& e2, P& r) { if (y < 0) return (x >= 0) + 2;
template<class P>
if ((e1-s1).cross(e2-s2)) { // i f not p a r a l l e l l if (y > 0) return (x <= 0);
int segmentIntersection(const P& s1, const P& e1,
r = s2-(e2-s2)*(e1-s1).cross(s2-s1)/(e1-s1).cross(e2-s2); return (x <= 0) * 2;
const P& s2, const P& e2, P& r1, P& r2) {
return 1; }
if (e1==s1) {
} else Angle t90() const { return {-y, x, t + (quad() == 3)}; }
if (e2==s2) {
Angle t180() const { return {-x, -y, t + (quad() >= 2)}; }
if (e1==e2) { r1 = e1; return 1; } // a l l equal return -((e1-s1).cross(s2-s1)==0 || s2==e2);
Angle t360() const { return {x, y, t + 1}; }
else return 0; // d i f f e r e n t point segments }
};
} else return segmentIntersection(s2,e2,s1,e1,r1,r2);//swap
bool operator<(Angle a, Angle b) {
}
//segment directions and separation sideOf.h // add a . dist2 () and b . dist2 () to also compare distances
P v1 = e1-s1, v2 = e2-s2, d = s2-s1; Description: Returns where p is as seen from s towards e. 1/0/-1 ⇔ left/on return make_tuple(a.t, a.quad(), a.y * (ll)b.x) <
line/right. If the optional argument eps is given 0 is returned if p is within make_tuple(b.t, b.quad(), a.x * (ll)b.y);
auto a = v1.cross(v2), a1 = v1.cross(d), a2 = v2.cross(d);
distance eps from the line. P is supposed to be Point<T> where T is e.g. }
if (a == 0) { // i f p a r a l l e l
auto b1=s1.dot(v1), c1=e1.dot(v1), double or long long. It uses products in intermediate steps so watch out for
overflow if using int or long long. // Given two points , t h i s calculates the smallest angle between
b2=s2.dot(v1), c2=e2.dot(v1);
Usage: bool left = sideOf(p1,p2,q)==1; // them, i . e . , the angle that covers the defined l i n e segment .
if (a1 || a2 || max(b1,min(b2,c2))>min(c1,max(b2,c2)))
"Point.h" 11 lines pair<Angle, Angle> segmentAngles(Angle a, Angle b) {
return 0;
template<class P> if (b < a) swap(a, b);
r1 = min(b2,c2)<b1 ? s1 : (b2<c2 ? s2 : e2);
int sideOf(const P& s, const P& e, const P& p) { return (b < a.t180() ?
r2 = max(b2,c2)>c1 ? e1 : (b2>c2 ? s2 : e2);
auto a = (e-s).cross(p-s); make_pair(a, b) : make_pair(b, a.t360()));
return 2-(r1==r2);
return (a > 0) - (a < 0); }
}
} Angle operator+(Angle a, Angle b) { // point a + vector b
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
template<class P> Angle r(a.x + b.x, a.y + b.y, a.t);
if (0<a1 || a<-a1 || 0<a2 || a<-a2)
int sideOf(const P& s, const P& e, const P& p, double eps) { if (a.t180() < r) r.t--;
return 0;
auto a = (e-s).cross(p-s); return r.t180() < a ? r.t360() : r;
r1 = s1-v1*a2/a;
double l = (e-s).dist()*eps; }
return 1;
return (a > l) - (a < -l); Angle angleDiff(Angle a, Angle b) { // angle b − angle a
}
} int tu = b.t - a.t; a.t = b.t;
return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x, tu - (b < a)};
}
onSegment.h
Description: Returns true iff p lies on the line segment from s to e. In-
SegmentIntersectionQ.h tended for use with e.g. Point<long long> where overflow is an issue. Use 8.2 Circles
Description: Like segmentIntersection, but only returns true/false. Prod- (segDist(s,e,p)<=epsilon) instead when using Point<double>.
ucts of three coordinates are used in intermediate steps so watch out for "Point.h" 5 lines
overflow if using int or long long. template<class P> CircleIntersection.h
"Point.h" 16 lines bool onSegment(const P& s, const P& e, const P& p) { Description: Computes a pair of points at which two circles intersect. Re-
template<class P> P ds = p-s, de = p-e; turns false in case of no intersection.
bool segmentIntersectionQ(P s1, P e1, P s2, P e2) { return ds.cross(de) == 0 && ds.dot(de) <= 0; "Point.h" 14 lines
typedef Point<ll> P;
"Point.h" 9 lines //or : i f ( segDist (∗ i , ∗j , p) <= epsilon ) return ! s t r i c t ;
pair<vi, vi> ulHull(const vector<P>& S) {
typedef Point<double> P; //increment n i f segment intersects l i n e from p
vi Q(sz(S)), U, L;
double ccRadius(const P& A, const P& B, const P& C) { n += (max(i->y,j->y) > p.y && min(i->y,j->y) <= p.y &&
iota(all(Q), 0);
return (B-A).dist()*(C-B).dist()*(A-C).dist()/ ((*j-*i).cross(p-*i) > 0) == (i->y <= p.y));
sort(all(Q), [&S](int a, int b){ return S[a] < S[b]; });
abs((B-A).cross(C-A))/2; }
trav(it, Q) {
} return n&1; //inside i f odd number of intersections
#define ADDP(C, cmp) while (sz(C) > 1 && S[C[sz(C)-2]].cross(\
P ccCenter(const P& A, const P& B, const P& C) { }
S[it], S[C.back()]) cmp 0) C.pop_back(); C.push_back(it);
P b = C-A, c = B-A; ADDP(U, <=); ADDP(L, >=);
return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2; PolygonArea.h }
} Description: Returns twice the signed area of a polygon. Clockwise enu- return {U, L};
meration gives negative area. Watch out for overflow if using int as T! }
MinimumEnclosingCircle.h "Point.h" 6 lines
Description: Computes the minimum circle that encloses a set of points. template<class T> vi convexHull(const vector<P>& S) {
Time: expected O (n) T polygonArea2(vector<Point<T>>& v) { vi u, l; tie(u, l) = ulHull(S);
"circumcircle.h" 28 lines T a = v.back().cross(v[0]); if (sz(S) <= 1) return u;
rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]); if (S[u[0]] == S[u[1]]) return {0};
pair<double, P> mec2(vector<P>& S, P a, P b, int n) {
return a; l.insert(l.end(), u.rbegin()+1, u.rend()-1);
double hi = INFINITY, lo = -hi;
} return l;
rep(i,0,n) {
}
auto si = (b-a).cross(S[i]-a);
if (si == 0) continue; PolygonCenter.h
P m = ccCenter(a, b, S[i]); Description: Returns the center of mass for a polygon.
auto cr = (b-a).cross(m-a); "Point.h" 10 lines
PolygonDiameter.h
if (si < 0) hi = min(hi, cr); Description: Calculates the max squared distance of a set of points.
else lo = max(lo, cr); typedef Point<double> P; "ConvexHull.h" 19 lines
} Point<double> polygonCenter(vector<P>& v) { vector<pii> antipodal(const vector<P>& S, vi& U, vi& L) {
double v = (0 < lo ? lo : hi < 0 ? hi : 0); auto i = v.begin(), end = v.end(), j = end-1; vector<pii> ret;
P c = (a + b) / 2 + (b - a).perp() * v / (b - a).dist2(); Point<double> res{0,0}; double A = 0; int i = 0, j = sz(L) - 1;
return {(a - c).dist2(), c}; for (; i != end; j=i++) { while (i < sz(U) - 1 || j > 0) {
} res = res + (*i + *j) * j->cross(*i); ret.emplace_back(U[i], L[j]);
pair<double, P> mec(vector<P>& S, P a, int n) { A += j->cross(*i); if (j == 0 || (i != sz(U)-1 && (S[L[j]] - S[L[j-1]])
random_shuffle(S.begin(), S.begin() + n); } .cross(S[U[i+1]] - S[U[i]]) > 0)) ++i;
P b = S[0], c = (a + b) / 2; return res / A / 3; else --j;
double r = (a - c).dist2(); } }
rep(i,1,n) if ((S[i] - c).dist2() > r * (1 + 1e-8)) { return ret;
tie(r,c) = (n == sz(S) ? PolygonCut.h e }
mec(S, S[i], i) : mec2(S, a, S[i], i)); Description:
} Returns a vector with the vertices of a polygon with every- pii polygonDiameter(const vector<P>& S) {
return {r, c}; thing to the left of the line going from s to e cut away. vi U, L; tie(U, L) = ulHull(S);
} Usage: vector<P> p = ...; s pair<ll, pii> ans;
pair<double, P> enclosingCircle(vector<P> S) { p = polygonCut(p, P(0,0), P(1,0)); trav(x, antipodal(S, U, L))
assert(!S.empty()); auto r = mec(S, S[0], sz(S)); "Point.h", "lineIntersection.h" 15 lines ans = max(ans, {(S[x.first] - S[x.second]).dist2(), x});
return {sqrt(r.first), r.second}; return ans.second;
typedef Point<double> P;
} }
vector<P> polygonCut(const vector<P>& poly, P s, P e) {
KTH PointInsideHull LineHullIntersection closestPair kdTree 19
PointInsideHull.h hi = mid; if(*i != xa[split] && (**i-splitp).dist2() < 1e-12)
Description: Determine whether a point t lies inside a given polygon else lo = mid; return i1 = *i, i2 = xa[split], 0;// nasty special case !
(counter-clockwise order). The polygon must be such that every point on } if (**i < splitp) ly.push_back(*i);
the circumference is visible from the first point in the vector. It returns 0 return a[hi%N].second; else ry.push_back(*i);
for points outside, 1 for points on the circumference, and 2 for points inside. } } // assert (( signed ) l e f t y . s i z e () == s p l i t )
Time: O (log N ) It j1, j2; // Conquer
"Point.h", "sideOf.h", "onSegment.h" 22 lines bool isign(P a, P b, int x, int y, int s) { double a = cp_sub(ly.begin(), ly.end(), xa, i1, i2);
typedef Point<ll> P; return sgn(a.cross(p[x], b)) * sgn(a.cross(p[y], b)) == s; double b = cp_sub(ry.begin(), ry.end(), xa+split, j1, j2);
int insideHull2(const vector<P>& H, int L, int R, const P& p) { } if(b < a) a = b, i1 = j1, i2 = j2;
int len = R - L; double a2 = a*a;
if (len == 2) { int bs2(int lo, int hi, P a, P b) { for(IIt i = ya; i != yaend; ++i) { // Create s t r i p (y−sorted )
int sa = sideOf(H[0], H[L], p); int L = lo; double x = (*i)->x;
int sb = sideOf(H[L], H[L+1], p); if (hi < lo) hi += N; if(x >= splitx-a && x <= splitx+a) stripy.push_back(*i);
int sc = sideOf(H[L+1], H[0], p); while (hi - lo > 1) { }
if (sa < 0 || sb < 0 || sc < 0) return 0; int mid = (lo + hi) / 2; for(IIt i = stripy.begin(); i != stripy.end(); ++i) {
if (sb==0 || (sa==0 && L == 1) || (sc == 0 && R == sz(H))) if (isign(a, b, mid, L, -1)) hi = mid; const P &p1 = **i;
return 1; else lo = mid; for(IIt j = i+1; j != stripy.end(); ++j) {
return 2; } const P &p2 = **j;
} return lo; if(p2.y-p1.y > a) break;
int mid = L + len / 2; } double d2 = (p2-p1).dist2();
if (sideOf(H[0], H[mid], p) >= 0) if(d2 < a2) i1 = *i, i2 = *j, a2 = d2;
return insideHull2(H, mid, R, p); pii isct(P a, P b) { } }
return insideHull2(H, L, mid+1, p); int f = bs(a - b), j = bs(b - a); return sqrt(a2);
} if (isign(a, b, f, j, 1)) return {-1, -1}; }
int x = bs2(f, j, a, b)%N,
int insideHull(const vector<P>& hull, const P& p) { y = bs2(j, f, a, b)%N; template<class It> // I t i s random access iterators of point<T>
if (sz(hull) < 3) return onSegment(hull[0], hull.back(), p); if (a.cross(p[x], b) == 0 && double closestpair(It begin, It end, It &i1, It &i2 ) {
else return insideHull2(hull, 1, sz(hull), p); a.cross(p[x+1], b) == 0) return {x, x}; vector<It> xa, ya;
} if (a.cross(p[y], b) == 0 && assert(end-begin >= 2);
a.cross(p[y+1], b) == 0) return {y, y}; for (It i = begin; i != end; ++i)
if (a.cross(p[f], b) == 0) return {f, -1}; xa.push_back(i), ya.push_back(i);
LineHullIntersection.h if (a.cross(p[j], b) == 0) return {j, -1}; sort(xa.begin(), xa.end(), it_less<It>);
Description: Line-convex polygon intersection. The polygon must be ccw return {x, y}; sort(ya.begin(), ya.end(), y_it_less<It>);
and have no colinear points. isct(a, b) returns a pair describing the inter- } return cp_sub(ya.begin(), ya.end(), xa.begin(), i1, i2);
section of a line with the polygon: • (−1, −1) if no collision, • (i, −1) 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 8.4 Misc. Point Set Problems kdTree.h
the line hits the polygon. Description: KD-tree (2d, can be extended to 3d)
Time: O (N + Q log n) "Point.h" 63 lines
"Point.h" 63 lines closestPair.h typedef long long T;
ll sgn(ll a) { return (a > 0) - (a < 0); } Description: i1, i2 are the indices to the closest pair of points in the point typedef Point<T> P;
typedef Point<ll> P; vector p after the call. The distance is returned. const T INF = numeric_limits<T>::max();
struct HullIntersection { Time: O (n log n)
int N; "Point.h" 58 lines bool on_x(const P& a, const P& b) { return a.x < b.x; }
vector<P> p; template<class It> bool on_y(const P& a, const P& b) { return a.y < b.y; }
vector<pair<P, int>> a; bool it_less(const It& i, const It& j) { return *i < *j; }
template<class It> struct Node {
HullIntersection(const vector<P>& ps) : N(sz(ps)), p(ps) { bool y_it_less(const It& i,const It& j) {return i->y < j->y;} P pt; // i f t h i s i s a leaf , the single point in i t
p.insert(p.end(), all(ps)); T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; // bounds
int b = 0; template<class It, class IIt> /∗ I I t = vector<It >:: iterator ∗/ Node *first = 0, *second = 0;
rep(i,1,N) if (P{p[i].y,p[i].x} < P{p[b].y, p[b].x}) b = i; double cp_sub(IIt ya, IIt yaend, IIt xa, It &i1, It &i2) {
rep(i,0,N) { typedef typename iterator_traits<It>::value_type P; T distance(const P& p) { // min squared distance to a point
int f = (i + b) % N; int n = yaend-ya, split = n/2; T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x);
a.emplace_back(p[f+1] - p[f], f); if(n <= 3) { // base case T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y);
} double a = (*xa[1]-*xa[0]).dist(), b = 1e50, c = 1e50; return (P(x,y) - p).dist2();
} if(n==3) b=(*xa[2]-*xa[0]).dist(), c=(*xa[2]-*xa[1]).dist() }
;
int qd(P p) { if(a <= b) { i1 = xa[1]; Node(vector<P>&& vp) : pt(vp[0]) {
return (p.y < 0) ? (p.x >= 0) + 2 if(a <= c) return i2 = xa[0], a; for (P p : vp) {
: (p.x <= 0) * (1 + (p.y <= 0)); else return i2 = xa[2], c; x0 = min(x0, p.x); x1 = max(x1, p.x);
} } else { i1 = xa[2]; y0 = min(y0, p.y); y1 = max(y1, p.y);
if(b <= c) return i2 = xa[0], b; }
int bs(P dir) { else return i2 = xa[1], c; if (vp.size() > 1) {
int lo = -1, hi = N; } } // s p l i t on x i f the box i s wider than high (not best
while (hi - lo > 1) { vector<It> ly, ry, stripy; heuristic . . . )
int mid = (lo + hi) / 2; P splitp = *xa[split]; sort(all(vp), x1 - x0 >= y1 - y0 ? on_x : on_y);
if (make_pair(qd(dir), dir.y * a[mid].first.x) < double splitx = splitp.x; // divide by taking h a l f the array for each child (not
make_pair(qd(a[mid].first), dir.x * a[mid].first.y)) for(IIt i = ya; i != yaend; ++i) { // Divide // best performance with many duplicates in the middle)
KTH DelaunayTriangulation PolyhedronVolume Point3D 3dHull sphericalDistance KMP 20
int half = sz(vp)/2; Point3D.h
first = new Node({vp.begin(), vp.begin() + half}); Description: Class to handle points in 3D space. T can be e.g. double or rep(i,4,sz(A)) {
second = new Node({vp.begin() + half, vp.end()}); long long. 32 lines
rep(j,0,sz(FS)) {
} F f = FS[j];
} template<class T> struct Point3D { if(f.q.dot(A[i]) > f.q.dot(A[f.a])) {
}; typedef Point3D P; E(a,b).rem(f.c);
typedef const P& R; E(a,c).rem(f.b);
struct KDTree { T x, y, z; E(b,c).rem(f.a);
Node* root; explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {} swap(FS[j--], FS.back());
KDTree(const vector<P>& vp) : root(new Node({all(vp)})) {} bool operator<(R p) const { FS.pop_back();
return tie(x, y, z) < tie(p.x, p.y, p.z); } }
pair<T, P> search(Node *node, const P& p) { bool operator==(R p) const { }
if (!node->first) { return tie(x, y, z) == tie(p.x, p.y, p.z); } int nw = sz(FS);
// uncomment i f we should not find the point i t s e l f : P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); } rep(j,0,nw) {
// i f (p == node−>pt ) return {INF, P() }; P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); } F f = FS[j];
return make_pair((p - node->pt).dist2(), node->pt); P operator*(T d) const { return P(x*d, y*d, z*d); } #define C(a, b, c) if (E(a,b).cnt() != 2) mf(f.a, f.b, i, f.c);
} P operator/(T d) const { return P(x/d, y/d, z/d); } C(a, b, c); C(a, c, b); C(b, c, a);
T dot(R p) const { return x*p.x + y*p.y + z*p.z; } }
Node *f = node->first, *s = node->second; P cross(R p) const { }
T bfirst = f->distance(p), bsec = s->distance(p); return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); trav(it, FS) if ((A[it.b] - A[it.a]).cross(
if (bfirst > bsec) swap(bsec, bfirst), swap(f, s); } A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b);
T dist2() const { return x*x + y*y + z*z; } return FS;
// search c l o s e s t side f i r s t , other side i f needed double dist() const { return sqrt((double)dist2()); } };
auto best = search(f, p); //Azimuthal angle ( longitude ) to x−axis in interval [−pi , pi ]
if (bsec < best.first) double phi() const { return atan2(y, x); }
best = min(best, search(s, p)); //Zenith angle ( l a t i t u d e ) to the z−axis in interval [0 , pi ] sphericalDistance.h
return best; double theta() const { return atan2(sqrt(x*x+y*y),z); } Description: Returns the shortest distance on the sphere with radius ra-
} P unit() const { return *this/(T)dist(); } //makes d i s t ()=1 dius between the points with azimuthal angles (longitude) f1 (φ1 ) and f2 (φ2 )
//returns unit vector normal to ∗ t h i s and p from x axis and zenith angles (latitude) t1 (θ1 ) and t2 (θ2 ) from z axis. All
// find nearest point to a point , and i t s squared distance P normal(P p) const { return cross(p).unit(); } angles measured in radians. The algorithm starts by converting the spheri-
// ( requires an arbitrary operator< for Point) //returns point rotated ’ angle ’ radians ccw around axis cal coordinates to cartesian coordinates so if that is what you have you can
pair<T, P> nearest(const P& p) { P rotate(double angle, P axis) const { use only the two last rows. dx*radius is then the difference between the
return search(root, p); double s = sin(angle), c = cos(angle); P u = axis.unit(); two points in the x direction and d*radius is the total distance between the
} return u*dot(u)*(1-c) + (*this)*c - cross(u)*s; points. 8 lines
}; }
}; double sphericalDistance(double f1, double t1,
double f2, double t2, double radius) {
double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1);
DelaunayTriangulation.h 3dHull.h double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1);
Description: Computes the Delaunay triangulation of a set of points. Each Description: Computes all faces of the 3-dimension hull of a point set. *No double dz = cos(t2) - cos(t1);
circumcircle contains none of the input points. If any three points are colin- four points must be coplanar*, or else random results will be returned. All double d = sqrt(dx*dx + dy*dy + dz*dz);
ear or any four
are on the same circle, behavior is undefined. faces will point
Time: O n2 outwards. return radius*2*asin(d/2);
Time: O n2 }
"Point.h", "3dHull.h" 10 lines "Point3D.h" 49 lines
template<class P, class F> typedef Point3D<double> P3;
void delaunay(vector<P>& ps, F trifun) {
if (sz(ps) == 3) { int d = (ps[0].cross(ps[1], ps[2]) < 0);
Strings (9)
struct PR {
trifun(0,1+d,2-d); } void ins(int x) { (a == -1 ? a : b) = x; }
vector<P3> p3; void rem(int x) { (a == x ? a : b) = -1; }
KMP.h
trav(p, ps) p3.emplace_back(p.x, p.y, p.dist2()); Description: pi[x] computes the length of the longest prefix of s that ends
int cnt() { return (a != -1) + (b != -1); } at x, other than s[0..x] itself This is used by find to find all occurances of a
if (sz(ps) > 3) trav(t, hull3d(p3)) if ((p3[t.b]-p3[t.a]). int a, b;
cross(p3[t.c]-p3[t.a]).dot(P3(0,0,1)) < 0) string.
}; Usage: vi p = pi(pattern); vi occ = find(word, p);
trifun(t.a, t.c, t.b);
} Time: O (pattern) for pi, O (word + pattern) for find 16 lines
struct F { P3 q; int a, b, c; };
vi pi(const string& s) {
vector<F> hull3d(const vector<P3>& A) { vi p(sz(s));
assert(sz(A) >= 4); rep(i,1,sz(s)) {
8.5 3D vector<vector<PR>> E(sz(A), vector<PR>(sz(A), {-1, -1})); int g = p[i-1];
#define E(x,y) E[f.x][f.y] while (g && s[i] != s[g]) g = p[g-1];
vector<F> FS; p[i] = g + (s[i] == s[g]);
PolyhedronVolume.h auto mf = [&](int i, int j, int k, int l) { }
Description: Magic formula for the volume of a polyhedron. Faces should P3 q = (A[j] - A[i]).cross((A[k] - A[i])); return p;
point outwards. 6 lines if (q.dot(A[l]) > q.dot(A[i])) }
q = q * -1;
template<class V, class L>
F f{q, i, j, k}; vi match(const string& s, const string& pat) {
double signed_poly_volume(const V& p, const L& trilist) {
E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i); vi p = pi(pat + ’\0’ + s), res;
double v = 0;
FS.push_back(f); rep(i,sz(p)-sz(s),sz(p))
trav(i, trilist) v += p[i.a].cross(p[i.b]).dot(p[i.c]);
}; if (p[i] == sz(pat)) res.push_back(i - 2 * sz(pat));
return v / 6;
rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4) return res;
}
mf(i, j, k, 6 - i - j - k); }
KTH Manacher MinRotation SuffixArray SuffixTree Hashing 21
Manacher.h memset(s, 0, sizeof s);
Description: For each position in a string, computes p[0][i] = half length int q = 8; memset(t, -1, sizeof t);
of longest even palindrome around pos i, p[1][i] = longest odd (half rounded while ((1 << q) < N) q++; fill(t[1],t[1]+ALPHA,0);
down). for (int moc = 0;; moc++) { s[0] = 1; l[0] = l[1] = -1; r[0] = r[1] = p[0] = p[1] = 0;
Time: O (N ) 11 lines
count_sort(b, q); // sort ( a l l (b) ) can be used as well rep(i,0,sz(a)) ukkadd(i, toi(a[i]));
a[b[0].second] = 0; }
void manacher(const string& s) { rep(i,1,N)
int n = sz(s); a[b[i].second] = a[b[i - 1].second] + // example : find longest common substring ( uses ALPHA = 28)
vi p[2] = {vi(n+1), vi(n)}; (b[i - 1].first != b[i].first); pii best;
rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++) { int lcs(int node, int i1, int i2, int olen) {
int t = r-i+!z; if ((1 << moc) >= N) break; if (l[node] <= i1 && i1 < r[node]) return 1;
if (i<r) p[z][i] = min(t, p[z][l+t]); rep(i,0,N) { if (l[node] <= i2 && i2 < r[node]) return 2;
int L = i-p[z][i], R = i+p[z][i]-!z; b[i].first = (ll)a[i] << q; int mask = 0, len = node ? olen + (r[node] - l[node]) : 0;
while (L>=1 && R+1<n && s[L-1] == s[R+1]) if (i + (1 << moc) < N) rep(c,0,ALPHA) if (t[node][c] != -1)
p[z][i]++, L--, R++; b[i].first += a[i + (1 << moc)]; mask |= lcs(t[node][c], i1, i2, len);
if (R>r) l=L, r=R; b[i].second = i; if (mask == 3)
}} } best = max(best, {len, r[node] - len});
} return mask;
MinRotation.h rep(i,0,sz(a)) a[i] = b[i].second; }
Description: Finds the lexicographically smallest rotation of a string. } static pii LCS(string s, string t) {
Usage: rotate(v.begin(), v.begin()+min rotation(v), v.end()); vi lcp() { SuffixTree st(s + (char)(’z’ + 1) + t + (char)(’z’ + 2));
Time: O (N ) // longest common prefixes : res [ i ] = lcp (a [ i ] , a [ i −1]) st.lcs(0, sz(s), sz(s) + 1 + sz(t), 0);
8 lines int n = sz(a), h = 0; return st.best;
int min_rotation(string s) { vi inv(n), res(n); }
int a=0, N=sz(s); s += s; rep(i,0,n) inv[a[i]] = i; };
rep(b,0,N) rep(i,0,N) { rep(i,0,n) if (inv[i] > 0) {
if (a+i == b || s[a+i] < s[b+i]) {b += max(0, i-1); break;} int p0 = a[inv[i] - 1];
if (s[a+i] > s[b+i]) { a = b; break; } while (s[i + h] == s[p0 + h]) h++; Hashing.h
} res[inv[i]] = h; Description: Various self-explanatory methods for string hashing. 44 lines
return a; if(h > 0) h--;
// Arithmetic mod 2ˆ64−1. 2x slower than mod 2ˆ64 and more
} }
// code , but works on e v i l t e s t data (e . g . Thue−Morse, where
return res;
// ABBA. . . and BAAB. . . of length 2ˆ10 hash the same mod 2ˆ64) .
}
SuffixArray.h // ”typedef u l l H;” instead i f you think t e s t data i s random,
};
Description: Builds suffix array for a string. a[i] is the starting index of the // or work mod 10ˆ9+7 i f the Birthday paradox i s not a problem .
suffix which is i-th in the sorted suffix array. The returned vector is of size struct H {
n + 1, and a[0] = n. The lcp function calculates longest common prefixes SuffixTree.h typedef uint64_t ull;
for neighbouring strings in suffix array. The returned vector is of size n + 1, Description: Ukkonen’s algorithm for online suffix tree construction. Each ull x; H(ull x=0) : x(x) {}
and ret[0] = 0. node contains indices [l, r) into the string, and a list of child nodes. Suffixes #define OP(O,A,B) H operator O(H o) { ull r = x; asm \
Memory: O (N ) are given by traversals of this tree, joining [l, r) substrings. The root is 0 (has (A "addq %%rdx, %0\n adcq $0,%0" : "+a"(r) : B); return r; }
Time: O N log2 N where N is the length of the string for creation of the l = -1, r = 0), non-existent children are -1. To get a complete tree, append OP(+,,"d"(o.x)) OP(*,"mul %1\n", "r"(o.x) : "rdx")
SA. O (N ) for longest common prefixes. a dummy symbol – otherwise it may contain an incomplete path (still useful H operator-(H o) { return *this + ∼o.x; }
61 lines ull get() const { return x + !∼x; }
for substring matching, though).
typedef pair<ll, int> pli; Time: O (26N ) bool operator==(H o) const { return get() == o.get(); }
void count_sort(vector<pli> &b, int bits) { // ( optional ) 50 lines bool operator<(H o) const { return get() < o.get(); }
// t h i s i s j u s t 3 times fas t e r than s t l sort for N=10ˆ6 struct SuffixTree { };
int mask = (1 << bits) - 1; enum { N = 200010, ALPHA = 26 }; // N ∼ 2∗maxlen+10 static const H C = (ll)1e11+3; // (order ∼ 3e9 ; random also ok)
rep(it,0,2) { int toi(char c) { return c - ’a’; }
int move = it * bits; string a; // v = cur node , q = cur position struct HashInterval {
vi q(1 << bits), w(sz(q) + 1); int t[N][ALPHA],l[N],r[N],p[N],s[N],v=0,q=0,m=2; vector<H> ha, pw;
rep(i,0,sz(b)) HashInterval(string& str) : ha(sz(str)+1), pw(ha) {
q[(b[i].first >> move) & mask]++; void ukkadd(int i, int c) { suff: pw[0] = 1;
partial_sum(q.begin(), q.end(), w.begin() + 1); if (r[v]<=q) { rep(i,0,sz(str))
vector<pli> res(b.size()); if (t[v][c]==-1) { t[v][c]=m; l[m]=i; ha[i+1] = ha[i] * C + str[i],
rep(i,0,sz(b)) p[m++]=v; v=s[v]; q=r[v]; goto suff; } pw[i+1] = pw[i] * C;
res[w[(b[i].first >> move) & mask]++] = b[i]; v=t[v][c]; q=l[v]; }
swap(b, res); } H hashInterval(int a, int b) { // hash [ a , b)
} if (q==-1 || c==toi(a[q])) q++; else { return ha[b] - ha[a] * pw[b - a];
} l[m+1]=i; p[m+1]=m; l[m]=l[v]; r[m]=q; }
struct SuffixArray { p[m]=p[v]; t[m][c]=m+1; t[m][toi(a[q])]=v; };
vi a; l[v]=q; p[v]=m; t[p[m]][toi(a[l[m]])]=m;
string s; v=s[p[m]]; q=l[m]; vector<H> getHashes(string& str, int length) {
SuffixArray(const string& _s) : s(_s + ’\0’) { while (q<r[m]) { v=t[v][toi(a[q])]; q+=r[v]-l[v]; } if (sz(str) < length) return {};
int N = sz(s); if (q==r[m]) s[m]=v; else s[m]=m+2; H h = 0, pw = 1;
vector<pli> b(N); q=r[v]-(q-r[m]); m+=2; goto suff; rep(i,0,length)
a.resize(N); } h = h * C + str[i], pw = pw * C;
rep(i,0,N) { } vector<H> ret = {h};
b[i].first = s[i]; rep(i,length,sz(str)) {
b[i].second = i; SuffixTree(string a) : a(a) { ret.push_back(h = h * C + str[i] - pw * str[i-length]);
} fill(r,r+N,sz(a)); }
KTH AhoCorasick IntervalContainer IntervalCover ConstantIntervals TernarySearch 22
return ret; vector<vi> findAll(vector<string>& pat, string word) { }
} vi r = find(word); if (mx.second == -1) return {};
vector<vi> res(sz(word)); cur = mx.first;
H hashString(string& s) { H h{}; trav(c,s) h=h*C+c; return h; } rep(i,0,sz(word)) { R.push_back(mx.second);
int ind = r[i]; }
while (ind != -1) { return R;
AhoCorasick.h res[i - sz(pat[ind]) + 1].push_back(ind); }
Description: Aho-Corasick tree is used for multiple pattern matching. Ini- ind = backp[ind];
tialize the tree with create(patterns). find(word) returns for each position }
the index of the longest√ word that ends there, or -1 if none. findAll( , word) }
finds all words (up to N N many if no duplicate patterns) that start at each return res; ConstantIntervals.h
position (shortest first). Duplicate patterns are allowed; empty patterns are } Description: Split a monotone function on [from, to) into a minimal set of
not. To find the longest words that start at each position, reverse all input. }; half-open intervals on which it has the same value. Runs a callback g for
Time: Function create is O (26N ) where N is the sum of length of patterns. each such interval.
find is O (M ) where M is the length of the word. findAll is O (N M ). 67 lines Usage: constantIntervals(0, sz(v), [&](int x){return v[x];},
struct AhoCorasick { Various (10) [&](int lo, int hi, T val){...});
Time: O k log n
enum {alpha = 26, first = ’A’}; k 19 lines
struct Node {
// (nmatches i s optional )
10.1 Intervals template<class F, class G, class T>
void rec(int from, int to, F f, G g, int& i, T& p, T q) {
int back, next[alpha], start = -1, end = -1, nmatches = 0; if (p == q) return;
Node(int v) { memset(next, v, sizeof(next)); } IntervalContainer.h if (from == to) {
}; Description: Add and remove intervals from a set of disjoint intervals. g(i, to, p);
vector<Node> N; Will merge the added interval with any overlapping intervals in the set when i = to; p = q;
vector<int> backp; adding. Intervals are [inclusive, exclusive). } else {
void insert(string& s, int j) { Time: O (log N ) int mid = (from + to) >> 1;
23 lines
assert(!s.empty()); rec(from, mid, f, g, i, p, f(mid));
int n = 0; set<pii>::iterator addInterval(set<pii>& is, int L, int R) {
if (L == R) return is.end(); rec(mid+1, to, f, g, i, p, q);
trav(c, s) { }
int& m = N[n].next[c - first]; auto it = is.lower_bound({L, R}), before = it;
while (it != is.end() && it->first <= R) { }
if (m == -1) { n = m = sz(N); N.emplace_back(-1); } template<class F, class G>
else n = m; R = max(R, it->second);
before = it = is.erase(it); void constantIntervals(int from, int to, F f, G g) {
} if (to <= from) return;
if (N[n].end == -1) N[n].start = j; }
if (it != is.begin() && (--it)->second >= L) { int i = from; auto p = f(i), q = f(to-1);
backp.push_back(N[n].end); rec(from, to-1, f, g, i, p, q);
N[n].end = j; L = min(L, it->first);
R = max(R, it->second); g(i, to, q);
N[n].nmatches++; }
} is.erase(it);
AhoCorasick(vector<string>& pat) { }
N.emplace_back(-1); return is.insert(before, {L,R});
rep(i,0,sz(pat)) insert(pat[i], i); }
N[0].back = sz(N);
N.emplace_back(0); void removeInterval(set<pii>& is, int L, int R) {
if (L == R) return;
queue<int> q; auto it = addInterval(is, L, R);
for (q.push(0); !q.empty(); q.pop()) { auto r2 = it->second; 10.2 Misc. algorithms
int n = q.front(), prev = N[n].back; if (it->first == L) is.erase(it);
rep(i,0,alpha) { else (int&)it->second = L;
int &ed = N[n].next[i], y = N[prev].next[i]; if (R != r2) is.emplace(R, r2);
if (ed == -1) ed = y; } TernarySearch.h
else { Description: Find the smallest i in [a, b] that maximizes f (i), assuming
N[ed].back = y; that f (a) < . . . < f (i) ≥ · · · ≥ f (b). To reverse which of the sides allows
(N[ed].end == -1 ? N[ed].end : backp[N[ed].start])
IntervalCover.h non-strict inequalities, change the < marked with (A) to <=, and reverse
Description: Compute indices of smallest set of intervals covering another
= N[y].end; the loop at (B). To minimize f , change it to >, also at (B).
interval. Intervals should be [inclusive, exclusive). To support [inclusive,
N[ed].nmatches += N[y].nmatches; Usage: int ind = ternSearch(0,n-1,[&](int i){return a[i];});
inclusive], change (A) to add || R.empty(). Returns empty set on failure
q.push(ed); Time: O (log(b − a)) 13 lines
(or if G is empty).
} Time: O (N log N ) 19 lines template<class F>
}
int ternSearch(int a, int b, F f) {
} template<class T>
assert(a <= b);
} vi cover(pair<T, T> G, vector<pair<T, T>> I) {
while (b - a >= 5) {
vi find(string word) { vi S(sz(I)), R;
int mid = (a + b) / 2;
int n = 0; iota(all(S), 0);
if (f(mid) < f(mid+1)) // (A)
vi res; // l l count = 0; sort(all(S), [&](int a, int b) { return I[a] < I[b]; });
a = mid;
trav(c, word) { T cur = G.first;
else
n = N[n].next[c - first]; int at = 0;
b = mid+1;
res.push_back(N[n].end); while (cur < G.second) { // (A)
}
// count += N[n ] . nmatches ; pair<T, int> mx = make_pair(cur, -1);
rep(i,a+1,b+1) if (f(a) < f(i)) a = i; // (B)
} while (at < sz(I) && I[S[at]].first <= cur) {
return a;
return res; mx = max(mx, make_pair(I[S[at]].second, S[at]));
}
} at++;
KTH Karatsuba LIS LCS 23
Karatsuba.h
Description: Faster-than-naive convolution of two sequences: c[x] =
a[i]b[x − i]. Uses the identity (aX + b)(cX + d) = acX 2 + bd + ((a +
P
c)(b + d) − ac − bd)X. Doesn’t handle sequences of very different length well.
See also FFT, under the Numerical chapter.
Time: O N 1.6
LIS.h
Description: Compute indices for the longest increasing subsequence.
Time: O (N log N ) 17 lines
template<class I> vi lis(vector<I> S) {
vi prev(sz(S));
typedef pair<I, int> p;
vector<p> res;
rep(i,0,sz(S)) {
p el { S[i], i };
//S[ i]+1 for non−decreasing
auto it = lower_bound(all(res), p { S[i], 0 });
if (it == res.end()) res.push_back(el), it = --res.end();
*it = el;
prev[i] = it==res.begin() ?0:(it-1)->second;
}
int L = sz(res), cur = res.back().second;
vi ans(L);
while (L--) ans[L] = cur, cur = prev[cur];
return ans;
}
LCS.h
Description: Finds the longest common subsequence.
Memory: O (nm).
Time: O (nm) where n and m are the lengths of the sequences. 14 lines
template<class T> T lcs(const T &X, const T &Y) {
int a = sz(X), b = sz(Y);
vector<vi> dp(a+1, vi(b+1));
rep(i,1,a+1) rep(j,1,b+1)
dp[i][j] = X[i-1]==Y[j-1] ? dp[i-1][j-1]+1 :
max(dp[i][j-1],dp[i-1][j]);
int len = dp[a][b];
T ans(len,0);
while(a && b)
if(X[a-1]==Y[b-1]) ans[--len] = X[--a], --b;
else if(dp[a][b-1]>dp[a-1][b]) --b;
else --a;
return ans;
}
KTH DivideAndConquerDP KnuthDP BumpAllocator SmallPtr BumpAllocatorSTL Unrolling SIMD 24
10.3 Dynamic programming • rep(b,0,K) rep(i,0,(1 << K)) if (i & 1 Unrolling.h 5 lines
<< b) D[i] += D[iˆ(1 << b)]; computes all #define F {...; ++i;}
DivideAndConquerDP.h sums of subsets. int i = from;
Description: Given a[i] = minlo(i)≤k<hi(i) (f (i, k)) where the (minimal) while (i&3 && i < to) F // for alignment , i f needed
optimal k increases with i, computes a[i] for i = L..R − 1. while (i + 4 <= to) { F F F F }
Time: O ((N + (hi − lo)) log N ) 18 lines
10.5.2 Pragmas while (i < to) F
struct DP { // Modify at w i l l :
int lo(int ind) { return 0; } • #pragma GCC optimize ("Ofast") will make GCC SIMD.h
int hi(int ind) { return ind; } Description: Cheat sheet of SSE/AVX intrinsics, for doing arithmetic
ll f(int ind, int k) { return dp[ind][k]; }
auto-vectorize for loops and optimizes floating points on several numbers at once. Can provide a constant factor improvement
void store(int ind, int k, ll v) { res[ind] = pii(k, v); } better (assumes associativity and turns off denormals). of about 4, orthogonal to loop unrolling. Operations follow the pat-
tern " mm(256)? name (si(128|256)|epi(8|16|32|64)|pd|ps)". Not all
void rec(int L, int R, int LO, int HI) { are described here; grep for mm in /usr/lib/gcc/*/4.9/include/ for
if (L >= R) return;
• #pragma GCC target ("avx,avx2")can double performance more. If AVX is unsupported, try 128-bit operations, ”emmintrin.h” and
int mid = (L + R) >> 1; of vectorized code, but causes crashes on old machines. #define SSE and MMX before including it. For aligned memory use
pair<ll, int> best(LLONG_MAX, LO); mm malloc(size, 32) or int buf[N] alignas(32), but prefer loadu/s-
rep(k, max(LO,lo(mid)), min(HI,hi(mid))) toreu.
best = min(best, make_pair(f(mid, k), k));
• #pragma GCC optimize ("trapv") kills the program on 43 lines
#pragma GCC target ("avx2") // or sse4 .1
store(mid, best.second, best.first); integer overflows (but is really slow). #include "immintrin.h"
rec(L, mid, LO, best.second+1);
rec(mid+1, R, best.second, HI);
} BumpAllocator.h typedef __m256i mi;
void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); } Description: When you need to dynamically allocate many objects and #define L(x) _mm256_loadu_si256((mi*)&(x))
}; don’t care about freeing them. ”new X” otherwise has an overhead of some-
thing like 0.05us + 16 bytes per allocation. 8 lines
// High−l e v e l / s p e c i f i c methods :
// load (u)? si256 , store (u)? si256 , setzero si256 , mm malloc
KnuthDP.h // Either g l o b a l l y or in a single class : // blendv ( epi8 | ps | pd) ( z?y : x) , movemask epi8 ( h i b i t s of bytes )
Description: When doing DP on intervals: a[i][j] = mini<k<j (a[i][k] + static char buf[450 << 20]; // i32gather epi32 (addr , x , 4) : map addr [ ] over 32−b parts of x
a[k][j]) + f (i, j), where the (minimal) optimal k increases with both i void* operator new(size_t s) { // sad epu8 : sum of absolute differences of u8, outputs 4xi64
and j, one can solve intervals in increasing order of length, and search static size_t i = sizeof buf; // maddubs epi16 : dot product of unsigned i7 ’ s , outputs 16xi15
k = p[i][j] for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This is assert(s < i); // madd epi16 : dot product of signed i16 ’ s , outputs 8xi32
known as Knuth DP. Sufficient criteria for this are if f (b, c) ≤ f (a, d) and return (void*)&buf[i -= s]; // extractf128 si256 ( , i ) (256−>128) , cvtsi128 si32 (128−>lo32 )
f (a, c) + f (b, d) ≤ f (a, d) + f (b, c) for all a ≤ b ≤ c ≤ d. Consider also: } // permute2f128 si256(x , x ,1) swaps 128−b i t lanes
LineContainer(ch. Data structures), monotone queues, ternary search. void operator delete(void*) {} // shuffle epi32 (x , 3∗64+2∗16+1∗4+0) == x for each lane
Time: O N 2 // s h u f f l e e p i 8 (x , y) takes a vector instead of an imm
SmallPtr.h // Methods that work with most data types (append e . g . epi32 ) :
Description: A 32-bit pointer that points into BumpAllocator memory.
// set1 , blend ( i8?x : y) , add , adds ( sat . ) , mullo , sub , and/or ,
"BumpAllocator.h" 10 lines
10.4 Debugging tricks template<class T> struct ptr {
// andnot , abs , min, max, sign (1 ,x) , cmp( gt | eq) , unpack( lo | hi )
unsigned ind; int sumi32(mi m) { union {int v[8]; mi m;} u; u.m = m;
• signal(SIGSEGV, [](int) { Exit(0); }); ptr(T* p = 0) : ind(p ? unsigned((char*)p - buf) : 0) { int ret = 0; rep(i,0,8) ret += u.v[i]; return ret; }
assert(ind < sizeof buf);
converts segfaults into Wrong Answers. Similarly one }
mi zero() { return _mm256_setzero_si256(); }
mi one() { return _mm256_set1_epi32(-1); }
can catch SIGABRT (assertion failures) and SIGFPE T& operator*() const { return *(T*)(buf + ind); } bool all_zero(mi m) { return _mm256_testz_si256(m, m); }
T* operator->() const { return &**this; }
(zero divisions). GLIBCXX DEBUG violations generate T& operator[](int a) const { return (&**this)[a]; }
bool all_one(mi m) { return _mm256_testc_si256(m, one()); }
SIGABRT (or SIGSEGV on gcc 5.4.0 apparently). explicit operator bool() const { return ind; } ll example_filteredDotProduct(int n, short* a, short* b) {
}; int i = 0; ll r = 0;
• feenableexcept(29); kills the program on NaNs mi zero = _mm256_setzero_si256(), acc = zero;
while (i + 16 <= n) {
(1), 0-divs (4), infinities (8) and denormals (16). BumpAllocatorSTL.h mi va = L(a[i]), vb = L(b[i]); i += 16;
Description: BumpAllocator for STL containers.
va = _mm256_and_si256(_mm256_cmpgt_epi16(vb, va), va);
Usage: vector<vector<int, small<int>>> ed(N); 14 lines mi vp = _mm256_madd_epi16(va, vb);
10.5 Optimization tricks char buf[450 << 20] alignas(16); acc = _mm256_add_epi64(_mm256_unpacklo_epi32(vp, zero),
size_t buf_ind = sizeof buf; _mm256_add_epi64(acc, _mm256_unpackhi_epi32(vp, zero)));
10.5.1 Bit hacks }
template<class T> struct small { union {ll v[4]; mi m;} u; u.m = acc; rep(i,0,4) r += u.v[i];
typedef T value_type; for (;i<n;++i) if (a[i] < b[i]) r += a[i]*b[i]; // <− equiv
• x & -x is the least bit in x. small() {} return r;
template<class U> small(const U&) {} }
• for (int x = m; x; ) { --x &= m; ... } T* allocate(size_t n) {
loops over all subset masks of m (except m itself). buf_ind -= n * sizeof(T);
buf_ind &= 0 - alignof(T);
return (T*)(buf + buf_ind);
• c = x&-x, r = x+c; (((rˆx) >> 2)/c) | r }
is the next number after x with the same number of void deallocate(T*, size_t) {}
};
bits set.
KTH techniques 25
Techniques (A) Computation of binomial coefficients
Pigeon-hole principle
Knuth-Morris-Pratt
Tries
Inclusion/exclusion Rolling polynom 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
Euklidean 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 contigous subvector sum * Modular exponentiation by squaring Bidirectional search
Chinese remainder theorem Iterative deepening DFS / A*
Invariants
Fermat’s small theorem Data structures
Huffman encoding
Euler’s theorem LCA (2ˆk-jumps in trees in general)
Graph teory
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 algoritm
Hensel lifting Convex hull trick (wcipeg.com/wiki/Convex_hull_trick)
MST: Prim’s algoritm
Vieta root jumping Monotone queues / monotone stacks / sliding queues
Bellman-Ford
Game theory Sliding queue using 2 stacks
Konig’s theorem and vertex cover
Combinatorial games Persistent segment tree
Min-cost max flow
Game trees
Lovasz toggle
Mini-max
Matrix tree theorem
Nim
Maximal matching, general graphs
Games on graphs
Hopcroft-Karp
Games on graphs with loops
Hall’s marriage theorem
Grundy numbers
Graphical sequences
Bipartite games without repetition
Floyd-Warshall
General games without repetition
Eulercykler
Alpha-beta pruning
Flow networks
Probability theory
* Augumenting paths Optimization
* Edmonds-Karp Binary search
Bipartite matching
Ternary search
Min. path cover
Unimodality and convex functions
Topological sorting
Binary search on derivative
Strongly connected components
Numerical methods
2-SAT
Numeric integration
Cutvertices, cutedges och biconnected components
Newton’s method
Edge coloring
Root-finding with binary/ternary search
* Trees Golden section search
Vertex coloring
Matrices
* Bipartite graphs (=> trees) Gaussian elimination
* 3ˆn (special case of set cover) Exponentiation by squaring
Diameter and centroid
Sorting
K’th shortest path
Radix sort
Shortest cycle
Geometry
Dynamic programming
Coordinates and vectors
Knapsack
Coin change * Cross product
Longest common subsequence * Scalar product
Convex hull
Longest increasing subsequence
Polygon cut
Number of paths in a dag
Closest pair
Shortest path in a dag
Coordinate-compression
Dynprog over intervals
Quadtrees
Dynprog over subsets
KD-trees
Dynprog over probabilities
All segment-segment intersection
Dynprog over trees
Sweeping
3ˆn set cover
Discretization (convert to events and sweep)
Divide and conquer
Angle sweeping
Knuth optimization
Line sweeping
Convex hull optimizations
Discrete second derivatives
RMQ (sparse table a.k.a 2ˆk-jumps)
Strings
Bitonic cycle
Longest common substring
Log partitioning (loop over most restricted)
Palindrome subsequences
Combinatorics