CP Cheat Sheet
CP Cheat Sheet
bat 5 lines
++17 -g -Wall -Wshadow -fsanitize=address,
undefined && @echo off
2 Mathematics 1 9 Strings 19 "./$prog_name" setlocal
set prog=%1
2.1 Equations . . . . . . . . . . . . . . 1 g++ %prog%.cpp -o %prog% -DDeBuG -std=c++17 -g
2.2 Recurrences . . . . . . . . . . . . . 2 10 Various 20 stdc++.h 34 lines -Wall -Wshadow && .\%prog%
2.3 Trigonometry . . . . . . . . . . . . 2 10.1 Intervals . . . . . . . . . . . . . . . 20 #include <bits/stdc++.h> endlocal
2.4 Geometry . . . . . . . . . . . . . . 2 10.2 Misc. algorithms . . . . . . . . . . 21 using namespace std;
hash.sh
2.5 Derivatives/Integrals . . . . . . . . 2 10.3 Dynamic programming . . . . . . . 21 template <typename T> constexpr
3 lines
vector<vector<double>> tmp(n, vector<double if (abs(diag[i]) < 1e-9 * abs(super[i])) { copy(all(a), begin(in)); const ll mod = (119 << 23) + 1, root = 62; //
>(n)); // diag [ i ] == 0 rep(i,0,sz(b)) in[i].imag(b[i]); = 998244353
rep(i,0,n) tmp[i][i] = 1, col[i] = i; b[i+1] -= b[i] * diag[i+1] / super[i]; fft(in); // For p < 2^30 there i s also e . g . 5 << 25, 7
if (i+2 < n) b[i+2] -= b[i] * sub[i+1] / for (C& x : in) x *= x; << 26, 479 << 21
rep(i,0,n) { super[i]; rep(i,0,n) out[i] = in[-i & (n - 1)] - conj( // and 483 << 21 (same root ) . The l a s t two are
int r = i, c = i; diag[i+1] = sub[i]; tr[++i] = 1; in[i]); > 10^9.
rep(j,i,n) rep(k,i,n) } else { fft(out); typedef vector<ll> vl;
if (fabs(A[j][k]) > fabs(A[r][c])) diag[i+1] -= super[i]*sub[i]/diag[i]; rep(i,0,sz(res)) res[i] = imag(out[i]) / (4 void ntt(vl &a) {
r = j, c = k; b[i+1] -= b[i]*sub[i]/diag[i]; * n); int n = sz(a), L = 31 - __builtin_clz(n);
if (fabs(A[r][c]) < 1e-12) return i; } return res; static vl rt(2, 1);
BRACU FastSubsetTransform ModularArithmetic ModInverse ModPow ModLog ModSum ModMulLL ModSqrt FastEratosthenes MillerRabin 8
for (static int k = 2, s = 2; k < n; k *= 2,
s++) {
Number theory (5) return n * i - A[e];
return -1;
ll x = modpow(a, (s + 1) / 2, p);
ll b = modpow(a, s, p), g = modpow(n, s, p);
rt.resize(n); } for (;; r = m) {
ll z[] = {1, modpow(root, mod >> s)}; 5.1 Modular arithmetic ll t = b;
rep(i,k,2*k) rt[i] = rt[i / 2] * z[i & 1] ModularArithmetic.h ModSum.h for (m = 0; m < r && t != 1; ++m)
% mod; Description: Operators for modular arithmetic. You Description: Sums of mod’ed arithmetic progressions. t = t * t % p;
} need to set mod to some number first and then you can modsum(to, c, k, m) =
Pto−1 if (m == 0) return x;
i=0 (ki + c)%m. divsum is
vi rev(n); use the structure. similar but for floored division. ll gs = modpow(g, 1LL << (r - m - 1), p);
rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << "euclid.h" 35bfea, 18 lines Time: log(m), with a large constant. g = gs * gs % p;
L) / 2; 5c5bc5, 16 lines x = x * gs % p;
const ll mod = 17; // change to something e l s e typedef unsigned long long ull;
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[ b = b * g % p;
struct Mod { ull sumsq(ull to) { return to / 2 * ((to-1) |
i]]); }
ll x; 1); }
for (int k = 1; k < n; k *= 2) }
Mod(ll xx) : x(xx) {}
for (int i = 0; i < n; i += 2 * k) rep(j
Mod operator+(Mod b) { return Mod((x + b.x) ull divsum(ull to, ull c, ull k, ull m) {
,0,k) {
ll z = rt[j + k] * a[i + j + k] % mod, &
% mod); } ull res = k / m * sumsq(to) + c / m * to; 5.2 Primality
Mod operator-(Mod b) { return Mod((x - b.x +
ai = a[i + j];
mod) % mod); }
k %= m; c %= m; FastEratosthenes.h
a[i + j + k] = ai - z + (z > ai ? mod : if (!k) return res; Description: Prime sieve for generating all primes
Mod operator*(Mod b) { return Mod((x * b.x) ull to2 = (to * k + c) / m;
0); smaller than LIM.
% mod); } return res + (to - 1) * to2 - divsum(to2, m
ai += (ai + z >= mod ? z - mod : z); Time: LIM=1e9 ≈ 1.5s
Mod operator/(Mod b) { return *this * invert -1 - c, m, k); 6b2912, 20 lines
}
(b); } } const int LIM = 1e6;
}
Mod invert(Mod a) { bitset<LIM> isPrime;
vl conv(const vl &a, const vl &b) {
ll x, y, g = euclid(a.x, mod, x, y); ll modsum(ull to, ll c, ll k, ll m) { vi eratosthenes() {
if (a.empty() || b.empty()) return {};
assert(g == 1); return Mod((x + mod) % mod c = ((c % m) + m) % m; const int S = (int)round(sqrt(LIM)), R = LIM
int s = sz(a) + sz(b) - 1, B = 32 -
); k = ((k % m) + m) % m; / 2;
__builtin_clz(s), n = 1 << B;
} return to * c + k * sumsq(to) - m * divsum( vi pr = {2}, sieve(S+1); pr.reserve(int(LIM/
int inv = modpow(n, mod - 2);
Mod operator^(ll e) { to, c, k, m); log(LIM)*1.1));
vl L(a), R(b), out(n);
if (!e) return Mod(1); } vector<pii> cp;
L.resize(n), R.resize(n);
Mod r = *this ^ (e / 2); r = r * r; for (int i = 3; i <= S; i += 2) if (!sieve[i
ntt(L), ntt(R);
return e&1 ? *this * r : r; ]) {
rep(i,0,n) out[-i & (n - 1)] = (ll)L[i] * R[ ModMulLL.h
} cp.push_back({i, i * i / 2});
i] % mod * inv % mod; Description: Calculate a · b mod c (or ab mod c) for
}; for (int j = i * i; j <= S; j += 2 * i)
ntt(out); 0 ≤ a, b ≤ c ≤ 7.2 · 1018 .
return {out.begin(), out.begin() + s}; sieve[j] = 1;
Time: O (1) for modmul, O (log b) for modpow
} ModInverse.h bbbd8f, 11 lines }
Description: Pre-computation of modular inverses. As- typedef unsigned long long ull; for (int L = 1; L <= R; L += S) {
sumes LIM ≤ mod and that mod is a prime.6f684f, 3 lines ull modmul(ull a, ull b, ull M) { array<bool, S> block{};
ll ret = a * b - M * ull(1.L / M * a * b); for (auto &[p, idx] : cp)
const ll mod = 1000000007, LIM = 200000; return ret + M * (ret < 0) - M * (ret >= (ll for (int i=idx; i < S+L; idx = (i+=p))
FastSubsetTransform.h ll* inv = new ll[LIM] - 1; inv[1] = 1; )M); block[i-L] = 1;
Description: TransformX to a basis with fast convolu- rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[ } rep(i,0,min(S, R - L))
mod % i] % mod; if (!block[i]) pr.push_back((L + i) * 2
tions of the form c[z] = a[x] · b[y], where ⊕ is ull modpow(ull b, ull e, ull mod) {
z=x⊕y + 1);
one of AND, OR, XOR. The size of a must be a power ull ans = 1;
of two.
ModPow.h b83e45, 8 lines
for (; e; b = modmul(b, b, mod), e /= 2) }
if (e & 1) ans = modmul(ans, b, mod); for (int i : pr) isPrime[i] = 1;
Time: O (N log N ) 464cf3, 16 lines const ll mod = 1000000007; // f a st e r i f const return pr;
return ans;
void FST(vi& a, bool inv) { } }
ll modpow(ll b, ll e) {
for (int n = sz(a), step = 1; step < n; step
ll ans = 1;
*= 2) { for (; e; b = b * b % mod, e /= 2) ModSqrt.h MillerRabin.h
for (int i = 0; i < n; i += 2 * step) rep( Description: Tonelli-Shanks algorithm for modular Description: Deterministic Miller-Rabin primality test.
if (e & 1) ans = ans * b % mod;
j,i,i+step) { square roots. Finds x s.t. x2 = a (mod p) (−x gives Guaranteed to work for numbers up to 7 · 1018 ; for larger
return ans;
int &u = a[j], &v = a[j + step]; tie(u, the other solution). numbers, use Python and extend A randomly.
}
v) = Time: O log2 p worst case, O (log p) for most p
Time: 7 times the complexity of ab mod c.
inv ? pii(v - u, u) : pii(v, u + v); "ModPow.h" 19a793, 24 lines "ModMulLL.h" 60dcd1, 12 lines
// AND ModLog.h x ll sqrt(ll a, ll p) { bool isPrime(ull n) {
inv ? pii(v, u - v) : pii(u + v, u); Description: Returns the smallest x > 0 s.t. a = b
(mod m), or −1 if no such x exists. modLog(a,1,m) can a %= p; if (a < 0) a += p; if (n < 2 || n % 6 % 4 != 1) return (n | 1)
// OR
be used to √
calculate the order of a. if (a == 0) return 0; == 3;
pii(u + v, u - v);
Time: O m
assert(modpow(a, (p-1)/2, p) == 1); // e l s e ull A[] = {2, 325, 9375, 28178, 450775,
// XOR c040b8, 11 lines no solution 9780504, 1795265022},
}
ll modLog(ll a, ll b, ll m) { if (p % 4 == 3) return modpow(a, (p+1)/4, p) s = __builtin_ctzll(n-1), d = n >> s;
}
ll n = (ll) sqrt(m) + 1, e = 1, f = 1, j = ; for (ull a : A) { // ^ count t r a i l i n g
if (inv) for (int& x : a) x /= sz(a); // XOR
1; // a^(n+3)/8 or 2^(n+3)/8 * 2^(n=1)/4 works zeroes
only
unordered_map<ll, ll> A; i f p % 8 == 5 ull p = modpow(a%n, d, n), i = s;
}
while (j <= n && (e = f = e * a % m) != b % ll s = p - 1, n = 2; while (p != 1 && p != n - 1 && a % n && i
vi conv(vi a, vi b) {
m) int r = 0, m; --)
FST(a, 0); FST(b, 0);
A[e * b % m] = j++; while (s % 2 == 0) p = modmul(p, p, n);
rep(i,0,sz(a)) a[i] *= b[i];
if (e == b % m) return j; ++r, s /= 2; if (p != n-1 && i != s) return 0;
FST(a, 1); return a;
if (__gcd(m, e) == __gcd(m, b)) while (modpow(n, (p - 1) / 2, p) != p - 1) }
}
rep(i,2,n+2) if (A.count(e = e * f % m)) ++n; return 1;
BRACU Factor euclid CRT phiFunction ContinuedFractions FracBinarySearch IntPerm 9
} If (x, y) is one solution, then all solutions are FracBinarySearch.h The number of divisors of n is at most around
given by Description: Given f and N , finds the smallest fraction 100 for n < 5e4, 500 for n < 1e7, 2000 for
p/q ∈ [0, 1] such that f (p/q) is true, and p, q ≤ N . You
Factor.h may want to throw an exception from f if it finds an ex- n < 1e10, 200 000 for n < 1e19.
kb ka act solution, in which case N can be removed.
Description: Pollard-rho randomized factorization al- x+ ,y − , k∈Z 5.8 Mobius Function
gorithm. Returns prime factors of a number, in arbitrary gcd(a, b) gcd(a, b) Usage: fracBS([](Frac f) { return f.p>=3*f.q;
}, 10); // {1,3}
order (e.g. 2299-> {11, 19, 11}).
Time: O (log(N ))
0
n is not square free
Time: O n1/4 , less for numbers with small factors. 27ab3e, 25 lines
µ(n) = 1 n has even number of prime factors
"ModMulLL.h", "MillerRabin.h" a33cf6, 18 lines
phiFunction.h struct Frac { ll p, q; };
Description: Euler’s ϕ function is defined as ϕ(n) :=
−1 n has odd number of prime factors
ull pollard(ull n) { # of positive integers ≤ n that are coprime with n.
auto f = [n](ull x) { return modmul(x, x, n) ϕ(1) = 1, p prime ⇒ ϕ(pk ) = (p − 1)pk−1 , m, n coprime template<class F>
+ 1; }; k k Frac fracBS(F f, ll N) { Mobius Inversion:
⇒ ϕ(mn) = ϕ(m)ϕ(n). If n = p1 1 p2 2 ...pk r
r then ϕ(n) = bool dir = 1, A = 1, B = 1; X X
ull x = 0, y = 0, t = 30, prd = 2, i = 1, q;
while (t++ % 40 || __gcd(prd, n) == 1) {
k −1
(p1 − 1)p1 1 ...(pr − 1)pk
r
r −1 . ϕ(n) = n ·
Q
p|n (1 − 1/p). Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to g(n) = f (d) ⇔ f (n) = µ(d)g(n/d)
search (0 , N]
P P
if (x == y) x = ++i, y = f(x); d|n ϕ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nϕ(n)/2, n > 1
d|n d|n
if ((q = modmul(prd, max(x,y) - min(x,y), if (f(lo)) return lo;
Euler’s thm: a, n coprime ⇒ aϕ(n) ≡ 1 (mod n).
n))) prd = q; assert(f(hi)); Other useful formulas/forms:
Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 cf7d6d,
(mod p) ∀a. while (A || B) {
x = f(x), y = f(f(y)); 8 lines P
ll adv = 0, step = 1; // move hi i f dir ,
} const int LIM = 5000000; d|n µ(d) = [n = 1] (very useful)
return __gcd(prd, n); int phi[LIM]; e l s e lo
for (int si = 0; step; (step *= 2) >>= si)
P
} g(n) = n|d f (d) ⇔ f (n) =
vector<ull> factor(ull n) { void calculatePhi() { { P
if (n == 1) return {}; rep(i,0,LIM) phi[i] = i&1 ? i : i/2; adv += step; n|d µ(d/n)g(d)
if (isPrime(n)) return {n}; for (int i = 3; i < LIM; i += 2) if(phi[i] Frac mid{lo.p * adv + hi.p, lo.q * adv + P n
ull x = pollard(n); == i) hi.q}; g(n) = 1≤m≤n f ( m ) ⇔ f (n) =
auto l = factor(x), r = factor(n / x); for (int j = i; j < LIM; j += i) phi[j] -= if (abs(mid.p) > N || mid.q > N || dir P n
l.insert(l.end(), all(r)); phi[j] / i; == !f(mid)) { 1≤m≤n µ(m)g( m )
return l; } adv -= step; si = 2;
}
}
}
Combinatorial (6)
5.4 Fractions hi.p += lo.p * adv;
ContinuedFractions.h hi.q += lo.q * adv; 6.1 Permutations
5.3 Divisibility Description: Given N and a real number x ≥ 0, finds dir = !dir;
the closest rational approximation p/q with p, q ≤ N . It swap(lo, hi); 6.1.1 Factorial
euclid.h A = B; B = !!adv;
Description: Finds two integers x and y, such that will obey |p/q − x| ≤ 1/qN .
For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . }
ax + by = gcd(a, b). If you just need gcd, use the built n 123 4 5 6 7 8 9 10
(pk /qk alternates between > x and < x.) If x is ratio- return dir ? hi : lo;
in gcd instead. If a and b are coprime, then x is the
nal, y eventually becomes ∞; if x is the root of a degree } n! 1 2 6 24 120 720 5040 40320 362880 3628800
inverse of a (mod b). 33ba8f, 5 lines
2 polynomial the a’s eventually become cyclic. n 11 12 13 14 15 16 17
ll euclid(ll a, ll b, ll &x, ll &y) { Time: O (log N ) dd6c5e, 21 lines 5.5 Pythagorean Triples
if (!b) return x = 1, y = 0, a; n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14
ll d = euclid(b, a % b, y, x); typedef double d; // for N ∼ 1e7 ; long double The Pythagorean triples are uniquely generated n 20 25 30 40 50 100 150 17
return y -= a/b * x, d; for N ∼ 1e9 by
} pair<ll, ll> approximate(d x, ll N) { n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL
ll LP = 0, LQ = 1, P = 1, Q = 0, inf =
LLONG_MAX; d y = x; a = k ·(m2 −n2 ), b = k ·(2mn), c = k ·(m2 +n2 ), IntPerm.h
CRT.h for (;;) { Description: Permutation -> integer conversion. (Not
Description: Chinese Remainder Theorem. ll lim = min(P ? (N-LP) / P : inf, Q ? (N- order preserving.) Integer -> permutation can use a
LQ) / Q : inf),
with m > n > 0, k > 0, m⊥n, and either m or n
crt(a, m, b, n) computes x such that x ≡ a (mod m), lookup table.
x ≡ b (mod n). If |a| < m and |b| < n, x will obey a = (ll)floor(y), b = min(a, lim), even. Time: O (n) 044568, 6 lines
0 ≤ x < lcm(m, n). Assumes mn < 262 . NP = b*P + LP, NQ = b*Q + LQ;
Time: log(n) if (a > b) { 5.6 Primes int permToInt(vi& v) {
// I f b > a/2, we have a semi=convergent 21
int use = 0, i = 0, r = 0;
"euclid.h" 04d93a, 7 lines
that gives us a
p = 962592769 is such that 2 | p − 1, which for(int x:v) r = r * ++i +
ll crt(ll a, ll m, ll b, ll n) { may be useful. For hashing use 970592641 __builtin_popcount(use & -(1<<x)),
// better approximation ; i f b = a/2, we
if (n > m) swap(a, b), swap(m, n);
*may* have one . (31-bit number), 31443539979727 (45-bit),
use |= 1 << x; // (
ll x, y, g = euclid(m, n, x, y); note : minus, not ∼! )
// Return {P, Q} here for a more
assert((a - b) % g == 0); // e l s e no
canonical approximation . 3006703054056749 (52-bit). There are 78498 return r;
solution }
x = (b - a) % n * x % n / g * m + a;
return (abs(x - (d)NP / (d)NQ) < abs(x - primes less than 1 000 000.
(d)P / (d)Q)) ?
return x < 0 ? x + m*n/g : x;
}
make_pair(NP, NQ) : make_pair(P, Q); Primitive roots exist modulo any prime power 6.1.2 Cycles
5.3.1 Bézout’s identity }
pa , except for p = 2, a > 2, and there are Let gS (n) be the number of n-permutations
if (abs(y = 1/(y - (d)a)) > 3*N) {
For a ̸=, b ̸= 0, then d = gcd(a, b) is the smallest return {NP, NQ}; ϕ(ϕ(pa )) many. For p = 2, a > 2, the group Z×
2a whose cycle lengths all belong to the set S.
positive integer for which there are integer } is instead isomorphic to Z2 × Z2a−2 . Then
LP = P; P = NP;
solutions to ∞
!
LQ = Q; Q = NQ;
5.7 Estimates X xn X xn
} gS (n) = exp
n! n
P
ax + by = d } d|n d = O(n log log n). n=0 n∈S
BRACU multinomial BellmanFord FloydWarshall TopoSort 10
6.1.3 Derangements c = c * ++m / (j+1); S(n, 1) = S(n, n) = 1 const ll inf = LLONG_MAX;
return c; struct Ed { int a, b, w, s() { return a < b ?
Permutations of a set such that none of the } k
!
a : -a; }};
1 X k n
elements appear in their original S(n, k) = (−1)k−j j struct Node { ll dist = inf; int prev = -1; };
position. 6.3 General purpose k! j=0
j
void bellmanFord(vector<Node>& nodes, vector<
numbers
Ed>& eds, int s) {
n n! 6.3.5 Bell numbers
D(n) = (n−1)(D(n−1)+D(n−2)) = nD(n−1)+(−1) =
6.3.1
nodes[s].dist = 0;
eBernoulli numbers Total number of partitions of n distinct sort(all(eds), [](Ed a, Ed b) { return a.s()
EGF of Bernoulli numbers is B(t) = et t−1 elements. B(n) =
< b.s(); });
6.1.4 Burnside’s lemma (FFT-able). 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, . . . . For p int lim = sz(nodes) / 2 + 2; // /3+100 with
Given a group G of symmetries and a set X, the B[0, . . .] = [1, − 21 , 16 , 0, − 30
1 1
, 0, 42 , . . .] prime, shuffled vertices
rep(i,0,lim) for (Ed ed : eds) {
number of elements of X up to symmetry Sums of powers: Node cur = nodes[ed.a], &dest = nodes[ed.b
equals n m
B(pm + n) ≡ mB(n) + B(n + 1) (mod p) ];
1 X g
X
m 1 X m + 1
|X |, n = Bk · (n + 1)m+1−k if (abs(cur.dist) == inf) continue;
|G| g∈G m + 1 k=0 k ll d = cur.dist + ed.w;
i=1 6.3.6 Labeled unrooted trees if (d < dest.dist) {
# on n vertices: nn−2 dest.prev = ed.a;
where X g are the elements fixed by g Euler-Maclaurin formula for infinite dest.dist = (i < lim-1 ? d : -inf);
sums: # on k existing trees of size ni : }
(g.x = x).
∞ Z ∞ ∞ n1 n2 · · · nk nk−2 }
X X Bk (k−1)
If f (n) counts “configurations” (of some sort) of f (i) = f (x)dx − f (m) # with degrees di : rep(i,0,lim) for (Ed e : eds) {
m k! if (nodes[e.a].dist == -inf)
length n, we can ignore rotational symmetry i=m k=1 (n − 2)!/((d1 − 1)! · · · (dn − 1)!) nodes[e.b].dist = -inf;
Z ∞ f (m) f ′ (m) f ′′′ (m)
using G = Zn to get }
≈ f (x)dx+ − + +O(f (5) (m)) 6.3.7 Catalan numbers }
m 2 12 720
n−1
1 X 1X
g(n) = f (gcd(n, k)) = f (k)ϕ(n/k). 6.3.2 Stirling numbers of the first ! ! !
n
k=0
n
k|n kind 1 2n 2n 2n (2n)! FloydWarshall.h
Cn = = − = Description: Calculates all-pairs shortest path in a di-
Number of permutations on n items with k n+1 n n n+1 (n + 1)!n! rected graph that might have negative edge weights. In-
6.2 Partitions and subsets cycles. put is an distance matrix m, where m[i][j] = inf if i and
j are not adjacent. As output, m[i][j] is set to the short-
2(2n + 1) X
6.2.1 Partition function c(n, k) = c(n − 1, k − 1) + (n − 1)c(n − 1, k), c(0, 0)C=0 = 1, Cn+1 =
1 Cn , Cn+1 = Ci Cn−i est distance between i and j, inf if no path, or -inf if
n+2 the path goes through a negative-weight cycle.
Number of ways of writing n as a sum of Pn Time: O N 3
k
positive integers, disregarding the order of the k=0 c(n, k)x = x(x + 1) . . . (x + n − 1) C n = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, ... 531245, 12 lines
}
return nu == access(&node[v])->first(); Edge e = heap[u]->top();
heap[u]->delta -= e.w, pop(heap[u]);
Geometry (8) template<class P>
double lineDist(const P& a, const P& b, const
void makeRoot(Node* u) { Q[qi] = e, path[qi++] = u, seen[u] = s; P& p) {
access(u);
u->splay();
res += e.w, u = uf.find(e.a);
if (seen[u] == s) {
8.1 Geometric primitives return (double)(b-a).cross(p-a)/(b-a).dist()
;
if(u->c[0]) { Node* cyc = 0; Point.h }
u->c[0]->p = 0; int end = qi, time = uf.time(); Description: Class to handle points in the plane. T can
u->c[0]->flip ^= 1; do cyc = merge(cyc, heap[w = path[--qi be e.g. double or long long. (Avoid int.) 47ec0a, 28 lines
u->c[0]->pp = u; ]]);
template <class T> int sgn(T x) { return (x > SegmentDistance.h
u->c[0] = 0; while (uf.join(u, w));
e resthe
0) - (x < 0); } Description:
u->fix(); u = uf.find(u), heap[u] = cyc, seen[u]
template<class T> Returns p shortest distance between point p and the line
} = -1; segment from point s to e.
struct Point {
} cycs.push_front({u, time, {&Q[qi], &Q[
typedef Point P;
Node* access(Node* u) { end]}});
T x, y;
s
u->splay(); } Usage: Point<double> a, b(2,2), p(1,1);
explicit Point(T x=0, T y=0) : x(x), y(y) {}
while (Node* pp = u->pp) { } bool onSegment = segDist(a,b,p) < 1e-10;
bool operator<(P p) const { return tie(x,y)
pp->splay(); u->pp = 0; rep(i,0,qi) in[uf.find(Q[i].b)] = Q[i]; "Point.h" 5c88f4, 6 lines
< tie(p.x,p.y); }
if (pp->c[1]) { } typedef Point<double> P;
bool operator==(P p) const { return tie(x,y)
pp->c[1]->p = 0; pp->c[1]->pp = pp; } double segDist(P& s, P& e, P& p) {
==tie(p.x,p.y); }
pp->c[1] = u; pp->fix(); u = pp; for (auto& [u,t,comp] : cycs) { // restore if (s==e) return (p-s).dist();
P operator+(P p) const { return P(x+p.x, y+p
} s o l ( optional ) auto d = (e-s).dist2(), t = min(d,max(.0,(p-
.y); }
return u; uf.rollback(t); s).dot(e-s)));
P operator-(P p) const { return P(x-p.x, y-p
} Edge inEdge = in[u]; return ((p-s)*d-(e-s)*t).dist()/d;
.y); }
}; for (auto& e : comp) in[uf.find(e.b)] = e; }
P operator*(T d) const { return P(x*d, y*d);
in[uf.find(inEdge.b)] = inEdge;
}
DirectedMST.h }
P operator/(T d) const { return P(x/d, y/d);
Description: Finds a minimum spanning tree/arbores- rep(i,0,n) par[i] = in[i].a;
} SegmentIntersection.h
cence of a directed graph, given a root node. If no MST return {res, par}; Description:
T dot(P p) const { return x*p.x + y*p.y; }
exists, returns -1. } If a unique intersection point between the line segments going
T cross(P p) const { return x*p.y - y*p.x; }
Time: O (E log V ) from s1 to e1 and from s2 to e2 exists then it is returned
T cross(P a, P b) const { return (a-*this).
39e620, 60 lines
If no intersection point exists an empty vector is returned
"../data-structures/UnionFindRollback.h" cross(b-*this); }
If infinitely many exist a vector with 2 elements is returned
struct Edge { int a, b; ll w; }; T dist2() const { return x*x + y*y; }
containing the endpoints of the common line segment. The
struct Node { double dist() const { return sqrt((double)
wrong position will be returned if P is Point<ll> and the in-
Edge key; dist2()); }
tersection point does not have integer coordinates. Products
Node *l, *r; // angle to x=axis in interval [= pi , pi ]
of three coordinates are used in intermediate steps so watch
ll delta; double angle() const { return atan2(y, x); }
out for overflow if using int or long long.
void prop() { P unit() const { return *this/dist(); } //
key.w += delta; makes d i s t ()=1 e1
if (l) l->delta += delta; P perp() const { return P(-y, x); } // e2
if (r) r->delta += delta; 7.8 Math rotates +90 degrees r1
delta = 0;
7.8.1 Number of Spanning P normal() const { return perp().unit(); } s1 s2
} // returns point rotated ’a ’ radians ccw
Edge top() { prop(); return key; } Trees around the origin Usage: vector<P> inter =
}; P rotate(double a) const { segInter(s1,e1,s2,e2);
Create an N × N matrix mat, and for each edge return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos( if (sz(inter)==1)
Node *merge(Node *a, Node *b) {
if (!a || !b) return a ?: b; a → b ∈ G, do mat[a][b]--, mat[b][b]++ a)); } cout << "segments intersect at " << inter[0]
a->prop(), b->prop(); (and mat[b][a]--, mat[a][a]++ if G is friend ostream& operator<<(ostream& os, P p) << endl;
if (a->key.w > b->key.w) swap(a, b); { "Point.h", "OnSegment.h" 9d57f2, 13 lines
swap(a->l, (a->r = merge(b, a->r)));
undirected). Remove the ith row and column return os << "(" << p.x << "," << p.y << " template<class P> vector<P> segInter(P a, P b,
return a; and take the determinant; this yields the )"; } P c, P d) {
} number of directed spanning trees rooted at i (if }; auto oa = c.cross(d, a), ob = c.cross(d, b),
void pop(Node*& a) { a->prop(); a = merge(a->l oc = a.cross(b, c), od = a.cross(b, d);
, a->r); } G is undirected, remove any // Checks i f intersection i s single non=
row/column). lineDistance.h endpoint point .
BRACU lineIntersection sideOf OnSegment linearTransformation Angle CircleIntersection CircleTangents CirclePolygonIntersection circumcircle 16
if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn( OnSegment.h // Given two points , t h i s calculates the P v = (d * dr + d.perp() * sqrt(h2) * sign
od) < 0) Description: Returns true iff p lies on the line segment smallest angle between ) / d2;
return {(a * ob - b * oa) / (ob - oa)}; from s to e. Use (segDist(s,e,p)<=epsilon) instead // them, i . e . , the angle that covers the out.push_back({c1 + v * r1, c2 + v * r2});
set<P> s; when using Point<double>. defined l i n e segment . }
if (onSegment(c, d, a)) s.insert(a); "Point.h" c597e8, 3 lines pair<Angle, Angle> segmentAngles(Angle a, if (h2 == 0) out.pop_back();
if (onSegment(c, d, b)) s.insert(b); template<class P> bool onSegment(P s, P e, P p Angle b) { return out;
if (onSegment(a, b, c)) s.insert(c); ) { if (b < a) swap(a, b); }
if (onSegment(a, b, d)) s.insert(d); return p.cross(s, e) == 0 && (s - p).dot(e - return (b < a.t180() ?
return {all(s)}; p) <= 0; make_pair(a, b) : make_pair(b, a.
} } t360()));
} CirclePolygonIntersection.h
Angle operator+(Angle a, Angle b) { // point a
lineIntersection.h linearTransformation.h + vector b Description: Returns the area of the intersection of a
Angle r(a.x + b.x, a.y + b.y, a.t);
Description: r p1
Description: circle with a ccw polygon.
If a unique intersection point of the lines going through s1,e1Apply the linear transformation (translation, rotation and if (a.t180() < r) r.t--; Time: O (n)
and s2,e2 exists {1, point} is returned. If no intersection point
scaling) which takes line p0-p1 to line q0-q1 to point r. return r.t180() < a ? r.t360() : r;
exists {0, (0,0)} is returned and if infinitely many exists {-1,p0 res }
"../../content/geometry/Point.h" a1ee63, 19 lines
(0,0)} is returned. The wrong position will be returned if P q0 Angle angleDiff(Angle a, Angle b) { // angle b typedef Point<double> P;
is Point<ll> and the intersection point does not have integer q1 = angle a #define arg(p, q) atan2(p.cross(q), p.dot(q))
coordinates. Products of three coordinates are used in inter- "Point.h" 03a306, 6 lines int tu = b.t - a.t; a.t = b.t; double circlePoly(P c, double r, vector<P> ps)
mediate steps so watch out for overflow if using int or ll. typedef Point<double> P; return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x {
, tu - (b < a)}; auto tri = [&](P p, P q) {
P linearTransformation(const P& p0, const P&
auto r2 = r * r / 2;
e2 r p1, }
P d = q - p;
const P& q0, const P& q1, const P& r) {
e1 s2 P dp = p1-p0, dq = q1-q0, num(dp.cross(dq),
auto a = d.dot(p)/d.dist2(), b = (p.dist2
s1 dp.dot(dq)); 8.2 Circles ()-r*r)/d.dist2();
auto det = a * a - b;
Usage: auto res = lineInter(s1,e1,s2,e2); return q0 + P((r-p0).cross(num), (r-p0).dot( CircleIntersection.h if (det <= 0) return arg(p, q) * r2;
if (res.first == 1) num))/dp.dist2(); Description: Computes the pair of points at which two auto s = max(0., -a-sqrt(det)), t = min
cout << "intersection point at " << } circles intersect. Returns false in case of no intersection. (1., -a+sqrt(det));
res.second << endl; "Point.h" 84d6d3, 11 lines if (t < 0 || 1 <= s) return arg(p, q) * r2
"Point.h" a01f81, 8 lines ;
Angle.h typedef Point<double> P;
template<class P> Description: A class for ordering angles (as represented bool circleInter(P a,P b,double r1,double r2, P u = p + d * s, v = p + d * t;
pair<int, P> lineInter(P s1, P e1, P s2, P e2) by int points and a number of rotations around the ori- pair<P, P>* out) { return arg(p,u) * r2 + u.cross(v)/2 + arg(
{ gin). Useful for rotational sweeping. Sometimes also rep- if (a == b) { assert(r1 != r2); return false v,q) * r2;
auto d = (e1 - s1).cross(e2 - s2); resents points or vectors. ; } };
if (d == 0) // i f p a r a l l e l Usage: vector<Angle> v = {w[0], w[0].t360() P vec = b - a; auto sum = 0.0;
return {-(s1.cross(e1, s2) == 0), P(0, 0)} ...}; // sorted double d2 = vec.dist2(), sum = r1+r2, dif = rep(i,0,sz(ps))
; int j = 0; rep(i,0,n) { while (v[j] < r1-r2, sum += tri(ps[i] - c, ps[(i + 1) % sz(ps)]
auto p = s2.cross(e1, e2), q = s2.cross(e2, v[i].t180()) ++j; } p = (d2 + r1*r1 - r2*r2)/(d2*2), h2 = - c);
s1); // sweeps j such that (j-i) represents the r1*r1 - p*p*d2; return sum;
return {1, (s1 * p + e1 * q) / d}; number of positively oriented triangles with if (sum*sum < d2 || dif*dif > d2) return }
} vertices at 0 and i false;
0f0602, 35 lines
P mid = a + vec*p, per = vec.perp() * sqrt(
struct Angle { fmax(0, h2) / d2);
sideOf.h int x, y; *out = {mid + per, mid - per}; circumcircle.h
Description: Returns where p is as seen from s towards int t; return true; Description:
e. 1/0/-1 ⇔ left/on line/right. If the optional argument Angle(int x, int y, int t=0) : x(x), y(y), t } The circumcirle of a triangle is the circle intersecting al
eps is given 0 is returned if p is within distance eps from (t) {} three vertices. ccRadius returns the radius of the circle going
the line. P is supposed to be Point<T> where T is e.g. Angle operator-(Angle b) const { return {x-b through points A, B and C and ccCenter returns the center
double or long long. It uses products in intermediate .x, y-b.y, t}; } CircleTangents.h of the same circle.
steps so watch out for overflow if using int or long long. int half() const { Description: Finds the external tangents of two circles, B
Usage: bool left = sideOf(p1,p2,q)==1; assert(x || y); or internal if r2 is negated. Can return 0, 1, or 2 tan- r c
"Point.h" 3af81c, 9 lines return y < 0 || (y == 0 && x < 0); gents – 0 if one circle contains the other (or overlaps it, C
template<class P> } in the internal case, or if the circles are the same); 1 if A
Angle t90() const { return {-y, x, t + (half the circles are tangent to each other (in which case .first
int sideOf(P s, P e, P p) { return sgn(s.cross "Point.h" 1caa3a, 9 lines
() && x >= 0)}; } = .second and the tangent line is perpendicular to the
(e, p)); } line between the centers). .first and .second give the tan- typedef Point<double> P;
Angle t180() const { return {-x, -y, t +
gency points at circle 1 and 2 respectively. To find the double ccRadius(const P& A, const P& B, const
template<class P> half()}; }
tangents of a circle with a point set r2 to 0. P& C) {
int sideOf(const P& s, const P& e, const P& p, Angle t360() const { return {x, y, t + 1}; }
"Point.h" b0153d, 13 lines return (B-A).dist()*(C-B).dist()*(A-C).dist
double eps) { };
()/
auto a = (e-s).cross(p-s); bool operator<(Angle a, Angle b) { template<class P>
abs((B-A).cross(C-A))/2;
double l = (e-s).dist()*eps; // add a . dist2 () and b . dist2 () to also vector<pair<P, P>> tangents(P c1, double r1, P
}
return (a > l) - (a < -l); compare distances c2, double r2) {
P ccCenter(const P& A, const P& B, const P& C)
} return make_tuple(a.t, a.half(), a.y * (ll)b P d = c2 - c1;
{
.x) < double dr = r1 - r2, d2 = d.dist2(), h2 = d2
P b = C-A, c = B-A;
make_tuple(b.t, b.half(), a.x * (ll)b - dr * dr;
return A + (b*c.dist2()-c*b.dist2()).perp()/
.y); if (d2 == 0 || h2 < 0) return {};
b.cross(c)/2;
} vector<pair<P, P>> out;
}
for (double sign : {-1, 1}) {
BRACU MinimumEnclosingCircle InsidePolygon PolygonArea PolygonCenter PolygonCut ConvexHull HullDiameter PointInsideHull LineHullIntersection ClosestPair 17
MinimumEnclosingCircle.h PolygonCenter.h HullDiameter.h if (extr(0)) return 0;
Description: Returns the center of mass for a polygon. Description: Returns the two points with max distance while (lo + 1 < hi) {
Description: Computes the minimum circle that en- Time: O (n) on a convex hull (ccw, no duplicate/collinear points). int m = (lo + hi) / 2;
closes a set of points. "Point.h" 9706dc, 9 lines Time: O (n) if (extr(m)) return m;
Time: expected O (n) typedef Point<double> P; "Point.h" c571b8, 12 lines int ls = cmp(lo + 1, lo), ms = cmp(m + 1,
"circumcircle.h" 09dd0a, 17 lines P polygonCenter(const vector<P>& v) { typedef Point<ll> P; m);
P res(0, 0); double A = 0; array<P, 2> hullDiameter(vector<P> S) { (ls < ms || (ls == ms && ls == cmp(lo, m))
pair<P, double> mec(vector<P> ps) { ? hi : lo) = m;
shuffle(all(ps), mt19937(time(0))); for (int i = 0, j = sz(v) - 1; i < sz(v); j int n = sz(S), j = n < 2 ? 0 : 1;
= i++) { pair<ll, array<P, 2>> res({0, {S[0], S[0]}}) }
P o = ps[0]; return lo;
double r = 0, EPS = 1 + 1e-8; res = res + (v[i] + v[j]) * v[j].cross(v[i ;
]); rep(i,0,j) }
rep(i,0,sz(ps)) if ((o - ps[i]).dist() > r *
EPS) { A += v[j].cross(v[i]); for (;; j = (j + 1) % n) {
} res = max(res, {(S[i] - S[j]).dist2(), { #define cmpL(i) sgn(a.cross(poly[i], b))
o = ps[i], r = 0; template <class P>
rep(j,0,i) if ((o - ps[j]).dist() > r * return res / A / 3; S[i], S[j]}});
} if ((S[(j + 1) % n] - S[j]).cross(S[i + array<int, 2> lineHull(P a, P b, vector<P>&
EPS) { poly) {
o = (ps[i] + ps[j]) / 2; 1] - S[i]) >= 0)
break; int endA = extrVertex(poly, (a - b).perp());
r = (o - ps[i]).dist(); PolygonCut.h } int endB = extrVertex(poly, (b - a).perp());
rep(k,0,j) if ((o - ps[k]).dist() > r * Description: if (cmpL(endA) < 0 || cmpL(endB) > 0)
Returns ea vector with the vertices of a polygon with every-
EPS) { return res.second;
} return {-1, -1};
o = ccCenter(ps[i], ps[j], ps[k]); thing to the left of the line going from s to e cut away. array<int, 2> res;
r = (o - ps[i]).dist(); rep(i,0,2) {
} PointInsideHull.h int lo = endB, hi = endA, n = sz(poly);
} s
Usage: vector<P> p = ...; Description: Determine whether a point t lies inside a while ((lo + 1) % n != hi) {
} p = polygonCut(p, P(0,0), P(1,0)); convex hull (CCW order, with no collinear points). Re- int m = ((lo + hi + (lo < hi ? 0 : n)) /
return {o, r}; "Point.h", "lineIntersection.h" f2b7d4, 13 lines turns true if point lies within the hull. If strict is true, 2) % n;
} points on the boundary aren’t included. (cmpL(m) == cmpL(endB) ? lo : hi) = m;
typedef Point<double> P;
Time: O (log N ) }
vector<P> polygonCut(const vector<P>& poly, P
"Point.h", "sideOf.h", "OnSegment.h" 71446b, 14 lines
s, P e) { res[i] = (lo + !cmpL(hi)) % n;
vector<P> res; typedef Point<ll> P; swap(endA, endB);
8.3 Polygons rep(i,0,sz(poly)) {
P cur = poly[i], prev = i ? poly[i-1] : bool inHull(const vector<P>& l, P p, bool
}
if (res[0] == res[1]) return {res[0], -1};
InsidePolygon.h poly.back(); strict = true) { if (!cmpL(res[0]) && !cmpL(res[1]))
Description: Returns true if p lies within the polygon. bool side = s.cross(e, cur) < 0; int a = 1, b = sz(l) - 1, r = !strict; switch ((res[0] - res[1] + sz(poly) + 1) %
If strict is true, it returns false for points on the bound- if (side != (s.cross(e, prev) < 0)) if (sz(l) < 3) return r && onSegment(l[0], l sz(poly)) {
ary. The algorithm uses products in intermediate steps res.push_back(lineInter(s, e, cur, prev) .back(), p); case 0: return {res[0], res[0]};
so watch out for overflow. .second); if (sideOf(l[0], l[a], l[b]) > 0) swap(a, b) case 2: return {res[1], res[1]};
Usage: vector<P> v = {P{4,4}, P{1,2}, P{2,1}}; if (side) ; }
bool in = inPolygon(v, P{3, 3}, false); res.push_back(cur); if (sideOf(l[0], l[a], p) >= r || sideOf(l return res;
Time: O (n) } [0], l[b], p)<= -r) }
"Point.h", "OnSegment.h", "SegmentDistance.h" 2bf504, 11 lines return res; return false;
template<class P> } while (abs(a - b) > 1) {
bool inPolygon(vector<P> &p, P a, bool strict int c = (a + b) / 2; 8.4 Misc. Point Set
= true) { (sideOf(l[0], l[c], p) > 0 ? b : a) = c;
int cnt = 0, n = sz(p);
ConvexHull.h } Problems
Description: return sgn(l[a].cross(l[b], p)) < r;
rep(i,0,n) {
Returns a vector of the points of the convex hull in counter-
}
ClosestPair.h
P q = p[(i + 1) % n]; Description: Finds the closest pair of points.
clockwise order. Points on the edge of the hull between two
if (onSegment(p[i], q, a)) return !strict; Time: O (n log n)
other points are not considered part of the hull.
//or : i f ( segDist (p [ i ] , q , a) <= eps) LineHullIntersection.h "Point.h" ac41a6, 17 lines
return ! s t r i c t ; Description: Line-convex polygon intersection. The typedef Point<ll> P;
cnt ^= ((a.y<p[i].y) - (a.y<q.y)) * a. polygon must be ccw and have no collinear points. line- pair<P, P> closest(vector<P> v) {
cross(p[i], q) > 0; Time: O (n log n)
Hull(line, poly) returns a pair describing the intersection assert(sz(v) > 1);
310954, 13 lines
of a line with the polygon: (−1, −1) if no collision,
"Point.h"
} set<P> S;
return cnt; typedef Point<ll> P; (i, −1) if touching the corner i, (i, i) if along side sort(all(v), [](P a, P b) { return a.y < b.y
} vector<P> convexHull(vector<P> pts) { (i, i + 1), (i, j) if crossing sides (i, i + 1) and (j, j + 1). ; });
if (sz(pts) <= 1) return pts; In the last case, if a corner i is crossed, this is treated as pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P
sort(all(pts)); happening on side (i, i + 1). The points are returned in ()}};
vector<P> h(sz(pts)+1); the same order as the line hits the polygon. extrVertex
PolygonArea.h int s = 0, t = 0; returns the point of a hull with the max projection onto
int j = 0;
Description: Returns twice the signed area of a poly- for (P p : v) {
for (int it = 2; it--; s = --t, reverse(all( a line.
gon. Clockwise enumeration gives negative area. Watch P d{1 + (ll)sqrt(ret.first), 0};
pts))) Time: O (log n)
out for overflow if using int as T! while (v[j].y <= p.y - d.x) S.erase(v[j
for (P p : pts) { "Point.h" 7cf45b, 39 lines
"Point.h" f12300, 6 lines ++]);
while (t >= s + 2 && h[t-2].cross(h[t
#define cmp(i,j) sgn(dir.perp().cross(poly[(i) auto lo = S.lower_bound(p - d), hi = S.
template<class T> -1], p) <= 0) t--;
%n]-poly[(j)%n])) upper_bound(p + d);
T polygonArea2(vector<Point<T>>& v) { h[t++] = p;
#define extr(i) cmp(i + 1, i) >= 0 && cmp(i, i for (; lo != hi; ++lo)
T a = v.back().cross(v[0]); }
- 1 + n) < 0 ret = min(ret, {(*lo - p).dist2(), {*lo,
rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]); return {h.begin(), h.begin() + t - (t == 2
template <class P> int extrVertex(vector<P>& p}});
return a; && h[0] == h[1])};
poly, P dir) { S.insert(p);
} }
int n = sz(poly), lo = 0, hi = n; }
BRACU kdTree FastDelaunay PolyhedronVolume Point3D 18
return ret.second; T bfirst = f->distance(p), bsec = s-> splice(q, a->next()); return pts;
} distance(p); splice(q->r(), b); }
if (bfirst > bsec) swap(bsec, bfirst), return q;
kdTree.h swap(f, s); } 8.5 3D
Description: KD-tree (2d, can be extended to 3d)
"Point.h" bac5b0, 63 lines
// search c l o s e s t side f i r s t , other side pair<Q,Q> rec(const vector<P>& s) { PolyhedronVolume.h
i f needed if (sz(s) <= 3) { Description: Magic formula for the volume of a poly-
typedef long long T; auto best = search(f, p); Q a = makeEdge(s[0], s[1]), b = makeEdge(s hedron. Faces should point outwards.
typedef Point<T> P; 3058c3, 6 lines
if (bsec < best.first) [1], s.back());
const T INF = numeric_limits<T>::max(); best = min(best, search(s, p)); if (sz(s) == 2) return { a, a->r() }; template<class V, class L>
return best; splice(a->r(), b); double signedPolyVolume(const V& p, const L&
bool on_x(const P& a, const P& b) { return a.x } auto side = s[0].cross(s[1], s[2]); trilist) {
< b.x; } Q c = side ? connect(b, a) : 0; double v = 0;
bool on_y(const P& a, const P& b) { return a.y // find nearest point to a point , and i t s return {side < 0 ? c->r() : a, side < 0 ? for (auto i : trilist) v += p[i.a].cross(p[i
< b.y; } squared distance c : b->r() }; .b]).dot(p[i.c]);
// ( requires an arbitrary operator< for } return v / 6;
struct Node { Point) }
P pt; // i f t h i s i s a leaf , the single point pair<T, P> nearest(const P& p) { #define H(e) e->F(), e->p
in i t return search(root, p); #define valid(e) (e->F().cross(H(base)) > 0) Point3D.h
T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; } Q A, B, ra, rb; Description: Class to handle points in 3D space. T can
// bounds }; int half = sz(s) / 2; be e.g. double or long long.
Node *first = 0, *second = 0; 8058ae, 32 lines
tie(ra, A) = rec({all(s) - half});
tie(B, rb) = rec({sz(s) - half + all(s)}); template<class T> struct Point3D {
T distance(const P& p) { // min squared FastDelaunay.h typedef Point3D P;
Description: Fast Delaunay triangulation. Each cir- while ((B->p.cross(H(A)) < 0 && (A = A->next
distance to a point ())) || typedef const P& R;
T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x cumcircle contains none of the input points. There must T x, y, z;
be no duplicate points. If all points are on a line, no tri- (A->p.cross(H(B)) > 0 && (B = B->r()
); ->o))); explicit Point3D(T x=0, T y=0, T z=0) : x(x)
T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y angles will be returned. Should work for doubles as well, , y(y), z(z) {}
though there may be precision issues in ’circ’. Returns Q base = connect(B->r(), A);
); if (A->p == ra->p) ra = base->r(); bool operator<(R p) const {
return (P(x,y) - p).dist2(); triangles in order {t[0][0], t[0][1], t[0][2], t[1][0], . . . }, all return tie(x, y, z) < tie(p.x, p.y, p.z);
counter-clockwise. if (B->p == rb->p) rb = base;
} }
Time: O (n log n) bool operator==(R p) const {
"Point.h" eefdf5, 88 lines
#define DEL(e, init, dir) Q e = init->dir; if
Node(vector<P>&& vp) : pt(vp[0]) { (valid(e)) \ return tie(x, y, z) == tie(p.x, p.y, p.z);
for (P p : vp) { typedef Point<ll> P; while (circ(e->dir->F(), H(base), e->F())) }
x0 = min(x0, p.x); x1 = max(x1, p.x); typedef struct Quad* Q; { \ P operator+(R p) const { return P(x+p.x, y+p
y0 = min(y0, p.y); y1 = max(y1, p.y); typedef __int128_t lll; // (can be l l i f Q t = e->dir; \ .y, z+p.z); }
} coords are < 2e4) splice(e, e->prev()); \ P operator-(R p) const { return P(x-p.x, y-p
if (vp.size() > 1) { P arb(LLONG_MAX,LLONG_MAX); // not equal to splice(e->r(), e->r()->prev()); \ .y, z-p.z); }
// s p l i t on x i f width >= height (not any other point e->o = H; H = e; e = t; \ P operator*(T d) const { return P(x*d, y*d,
ideal . . . ) } z*d); }
sort(all(vp), x1 - x0 >= y1 - y0 ? on_x struct Quad { for (;;) { P operator/(T d) const { return P(x/d, y/d,
: on_y); Q rot, o; P p = arb; bool mark; DEL(LC, base->r(), o); DEL(RC, base, prev z/d); }
// divide by taking h a l f the array for P& F() { return r()->p; } ()); T dot(R p) const { return x*p.x + y*p.y + z*
each child (not Q& r() { return rot->rot; } if (!valid(LC) && !valid(RC)) break; p.z; }
// best performance with many duplicates Q prev() { return rot->o->rot; } if (!valid(LC) || (valid(RC) && circ(H(RC) P cross(R p) const {
in the middle) Q next() { return r()->prev(); } , H(LC)))) return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p
int half = sz(vp)/2; } *H; base = connect(RC, base->r()); .y - y*p.x);
first = new Node({vp.begin(), vp.begin() else }
+ half}); bool circ(P p, P a, P b, P c) { // i s p in the base = connect(base->r(), LC->r()); T dist2() const { return x*x + y*y + z*z; }
second = new Node({vp.begin() + half, vp circumcircle? } double dist() const { return sqrt((double)
.end()}); lll p2 = p.dist2(), A = a.dist2()-p2, return { ra, rb }; dist2()); }
} B = b.dist2()-p2, C = c.dist2()-p2; } //Azimuthal angle ( longitude ) to x=axis in
} return p.cross(a,b)*C + p.cross(b,c)*A + p. interval [= pi , pi ]
}; cross(c,a)*B > 0; vector<P> triangulate(vector<P> pts) { double phi() const { return atan2(y, x); }
} sort(all(pts)); assert(unique(all(pts)) == //Zenith angle ( l a t i t u d e ) to the z=axis in
struct KDTree { Q makeEdge(P orig, P dest) { pts.end()); interval [0 , pi ]
Node* root; Q r = H ? H : new Quad{new Quad{new Quad{new if (sz(pts) < 2) return {}; double theta() const { return atan2(sqrt(x*x
KDTree(const vector<P>& vp) : root(new Node( Quad{0}}}}; Q e = rec(pts).first; +y*y),z); }
{all(vp)})) {} H = r->o; r->r()->r() = r; vector<Q> q = {e}; P unit() const { return *this/(T)dist(); }
rep(i,0,4) r = r->rot, r->p = arb, r->o = i int qi = 0; //makes d i s t ()=1
pair<T, P> search(Node *node, const P& p) { & 1 ? r : r->r(); while (e->o->F().cross(e->F(), e->p) < 0) e //returns unit vector normal to * t h i s and p
if (!node->first) { r->p = orig; r->F() = dest; = e->o; P normal(P p) const { return cross(p).unit()
// uncomment i f we should not find the return r; #define ADD { Q c = e; do { c->mark = 1; pts. ; }
point i t s e l f : } push_back(c->p); \ //returns point rotated ’ angle ’ radians ccw
// i f (p == node=>pt ) return {INF, P()}; void splice(Q a, Q b) { q.push_back(c->r()); c = c->next(); } while around axis
return make_pair((p - node->pt).dist2(), swap(a->o->rot->o, b->o->rot->o); swap(a->o, (c != e); } P rotate(double angle, P axis) const {
node->pt); b->o); ADD; pts.clear(); double s = sin(angle), c = cos(angle); P u
} } while (qi < sz(q)) if (!(e = q[qi++])->mark) = axis.unit();
Q connect(Q a, Q b) { ADD; return u*dot(u)*(1-c) + (*this)*c - cross(
Node *f = node->first, *s = node->second; Q q = makeEdge(a->F(), b->p); u)*s;
BRACU 3dHull sphericalDistance KMP Zfunc Manacher MinRotation SuffixArray SuffixTree 19
} Description: Returns the shortest distance on the Manacher.h (y[a] == y[b] && y[a + j] == y[b + j])
}; sphere with radius radius between the points with az- Description: For each position in a string, computes ? p - 1 : p++;
imuthal angles (longitude) f1 (ϕ1 ) and f2 (ϕ2 ) from x p[0][i] = half length of longest even palindrome around }
axis and zenith angles (latitude) t1 (θ1 ) and t2 (θ2 ) from pos i, p[1][i] = longest odd (half rounded down). rep(i,1,n) rank[sa[i]] = i;
3dHull.h z axis (0 = north pole). All angles measured in radians. Time: O (N ) e7ad79, 13 lines
for (int i = 0, j; i < n - 1; lcp[rank[i
Description: Computes all faces of the 3-dimension hull The algorithm starts by converting the spherical coordi- ++]] = k)
nates to cartesian coordinates so if that is what you have array<vi, 2> manacher(const string& s) { for (k && k--, j = sa[rank[i] - 1];
of a point set. *No four points must be coplanar*, or else int n = sz(s);
random results will be returned. All faces will point out- you can use only the two last rows. dx*radius is then the s[i + k] == s[j + k]; k++);
difference between the two points in the x direction and array<vi,2> p = {vi(n+1), vi(n)}; }
wards. rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++)
Time: O n2
d*radius is the total distance between the points.
611f07, 8 lines
};
{
"Point3D.h" 5b45fc, 49 lines double sphericalDistance(double f1, double t1, int t = r-i+!z;
typedef Point3D<double> P3; double f2, double t2, double radius) { if (i<r) p[z][i] = min(t, p[z][l+t]); SuffixTree.h
double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1 int L = i-p[z][i], R = i+p[z][i]-!z; Description: Ukkonen’s algorithm for online suffix tree
struct PR { ); while (L>=1 && R+1<n && s[L-1] == s[R+1]) construction. Each node contains indices [l, r) into the
void ins(int x) { (a == -1 ? a : b) = x; } double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1 p[z][i]++, L--, R++; string, and a list of child nodes. Suffixes are given by
void rem(int x) { (a == x ? a : b) = -1; } ); if (R>r) l=L, r=R; traversals of this tree, joining [l, r) substrings. The root
int cnt() { return (a != -1) + (b != -1); } double dz = cos(t2) - cos(t1); } is 0 (has l = -1, r = 0), non-existent children are -1. To
int a, b; double d = sqrt(dx*dx + dy*dy + dz*dz); return p; get a complete tree, append a dummy symbol – other-
}; return radius*2*asin(d/2); } wise it may contain an incomplete path (still useful for
} substring matching, though).
struct F { P3 q; int a, b, c; }; Time: O (26N )
MinRotation.h aae0b8, 50 lines
// High=l e v e l / s p e c i f i c methods :
// load (u)? si256 , store (u)? si256 ,
setzero si256 , mm malloc
// blendv ( epi8 | ps | pd) ( z?y : x) , movemask epi8
( h i b i t s of bytes )
// i32gather epi32 (addr , x , 4) : map addr [ ]
over 32=b parts of x
// sad epu8 : sum of absolute differences of u8
, outputs 4xi64
// maddubs epi16 : dot product of unsigned i7 ’ s
, outputs 16xi15
// madd epi16 : dot product of signed i16 ’ s ,
outputs 8xi32
// extractf128 si256 ( , i ) (256=>128) ,
cvtsi128 si32 (128=>lo32 )
// permute2f128 si256(x , x ,1) swaps 128= b i t
lanes
// shuffle epi32 (x , 3*64+2*16+1*4+0) == x for
each lane
// s h u f f l e e p i 8 (x , y) takes a vector instead
of an imm
ll example_filteredDotProduct(int n, short* a,
short* b) {
int i = 0; ll r = 0;
BRACU techniques 23