Omogen Heap: KTH Royal Institute of Technology
Omogen Heap: KTH Royal Institute of Technology
Omogen Heap
Simon Lindholm, Johan Sannemo, Mårten Wiman
2019-04-17
KTH template .bashrc .vimrc troubleshoot 1
Contest (1) Any possible infinite recursion?
tan v + tan w
tan(v + w) =
Invalidated pointers or iterators? 1 − tan v tan w
template.cpp Are you using too much memory?
15 lines Debug with resubmits (e.g. remapped signals, see Various).
v+w v−w
sin v + sin w = 2 sin cos
#include <bits/stdc++.h> 2 2
using namespace std; Time limit exceeded:
Do you have any possible infinite loops?
v+w v−w
cos v + cos w = 2 cos cos
#define rep(i, a, b) for(int i = a; i < (b); ++i) What is the complexity of your algorithm? 2 2
#define trav(a, x) for(auto& a : x) Are you copying a lot of unnecessary data? (References)
#define all(x) x.begin(), x.end() How big is the input and output? (consider scanf) (V + W ) tan(v − w)/2 = (V − W ) tan(v + w)/2
#define sz(x) (int)(x).size() Avoid vector, map. (use arrays/unordered_map)
typedef long long ll; What do your team mates think about your algorithm? where V, W are lengths of sides opposite angles v, w.
typedef pair<int, int> pii;
typedef vector<int> vi; Memory limit exceeded: a cos x + b sin x = r cos(x − φ)
What is the max amount of memory your algorithm should need?
int main() { Are you clearing all datastructures between test cases? a sin x + b cos x = r sin(x + φ)
cin.sync_with_stdio(0); cin.tie(0);
cin.exceptions(cin.failbit); √
} Mathematics (2) where r = a2 + b2 , φ = atan2(b, a).
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
Matrix.h struct FT {
Description: Basic operations on square matrices. vector<ll> s;
Usage: Matrix<int, 3> A;
Treap.h FT(int n) : s(n) {}
Description: A short self-balancing tree. It acts as a sequential container void update(int pos, ll dif) { // a [ pos ] += d i f
A.d = {{{{1,2,3}}, {{4,5,6}}, {{7,8,9}}}}; with log-time splits/joins, and is easy to augment with additional data.
vector<int> vec = {1,2,3}; for (; pos < sz(s); pos |= pos + 1) s[pos] += dif;
Time: O (log N ) 55 lines }
vec = (AˆN) * vec; 26 lines
struct Node { ll query(int pos) { // sum of values in [0 , pos)
template<class T, int N> struct Matrix { Node *l = 0, *r = 0; ll res = 0;
typedef Matrix M; int val, y, c = 1; for (; pos > 0; pos &= pos - 1) res += s[pos-1];
array<array<T, N>, N> d{}; Node(int val) : val(val), y(rand()) {} return res;
M operator*(const M& m) const { void recalc(); }
M a; }; int lower_bound(ll sum) {// min pos s t sum of [0 , pos ] >= sum
rep(i,0,N) rep(j,0,N) // Returns n i f no sum i s >= sum, or −1 i f empty sum i s .
rep(k,0,N) a.d[i][j] += d[i][k]*m.d[k][j]; int cnt(Node* n) { return n ? n->c : 0; } if (sum <= 0) return -1;
return a; void Node::recalc() { c = cnt(l) + cnt(r) + 1; } int pos = 0;
} for (int pw = 1 << 25; pw; pw >>= 1) {
vector<T> operator*(const vector<T>& vec) const { template<class F> void each(Node* n, F f) { if (pos + pw <= sz(s) && s[pos + pw-1] < sum)
vector<T> ret(N); if (n) { each(n->l, f); f(n->val); each(n->r, f); } pos += pw, sum -= s[pos-1];
rep(i,0,N) rep(j,0,N) ret[i] += d[i][j] * vec[j]; } }
return ret; return pos;
} pair<Node*, Node*> split(Node* n, int k) { }
M operatorˆ(ll p) const { if (!n) return {}; };
assert(p >= 0); if (cnt(n->l) >= k) { // ”n−>val >= v” for lower bound(v)
M a, b(*this); auto pa = split(n->l, k);
rep(i,0,N) a.d[i][i] = 1;
while (p) {
n->l = pa.second; FenwickTree2d.h
n->recalc(); Description: Computes sums a[i,j] for all i<I, j<J, and increases single ele-
if (p&1) a = a*b; return {pa.first, n};
b = b*b; ments a[i,j]. Requires that the elements to be updated are known in advance
} else { (call fakeUpdate() before init()).
p >>= 1;
}
auto pa = split(n->r, k - cnt(n->l) - 1); Time: O log2 N . (Use persistent segment trees for O (log N ).)
n->r = pa.first; "FenwickTree.h" 22 lines
return a; n->recalc();
} struct FT2 {
return {n, pa.second};
}; vector<vi> ys; vector<FT> ft;
}
FT2(int limx) : ys(limx) {}
}
void fakeUpdate(int x, int y) {
LineContainer.h Node* merge(Node* l, Node* r) {
for (; x < sz(ys); x |= x + 1) ys[x].push_back(y);
Description: Container where you can add lines of the form kx+m, and }
query maximum values at points x. Useful for dynamic programming. if (!l) return r;
void init() {
Time: O (log N ) if (!r) return l;
30 lines trav(v, ys) sort(all(v)), ft.emplace_back(sz(v));
if (l->y > r->y) {
}
struct Line { l->r = merge(l->r, r);
int ind(int x, int y) {
mutable ll k, m, p; l->recalc();
return (int)(lower_bound(all(ys[x]), y) - ys[x].begin()); }
bool operator<(const Line& o) const { return k < o.k; } return l;
void update(int x, int y, ll dif) {
bool operator<(ll x) const { return p < x; } } else {
for (; x < sz(ys); x |= x + 1)
}; r->l = merge(l, r->l);
ft[x].update(ind(x, y), dif);
r->recalc();
}
struct LineContainer : multiset<Line, less<>> { return r;
ll query(int x, int y) {
// ( for doubles , use i nf = 1/.0 , div (a , b) = a/b) }
ll sum = 0;
const ll inf = LLONG_MAX; }
for (; x; x &= x - 1)
ll div(ll a, ll b) { // floored division
sum += ft[x-1].query(ind(x-1, y));
return a / b - ((a ˆ b) < 0 && a % b); } Node* ins(Node* t, Node* n, int pos) {
return sum;
bool isect(iterator x, iterator y) { auto pa = split(t, pos);
}
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; }
KTH RMQ GoldenSectionSearch Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence HillClimbing 5
RMQ.h double b = a.back(), c; a.back() = 0; ll b = 1;
Description: Range Minimum Queries on an array. Returns min(V[a], V[a for(int i=sz(a)-1; i--;) c = a[i], a[i] = a[i+1]*x0+b, b=c; rep(i,0,n) { ++m;
+ 1], ... V[b - 1]) in constant time. a.pop_back(); ll d = s[i] % mod;
Usage: RMQ rmq(values); } rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
rmq.query(inclusive, exclusive); }; if (!d) continue;
Time: O (|V | log |V | + Q) 19 lines
T = C; ll coef = d * modpow(b, mod-2) % mod;
rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
template<class T> PolyRoots.h if (2 * L > i) continue;
struct RMQ { Description: Finds the real roots to a polynomial. L = i + 1 - L; B = T; b = d; m = 0;
vector<vector<T>> jmp; Usage: poly roots({{2,-3,1}},-1e9,1e9) // solve xˆ2-3x+2 = 0 }
Time: O n2 log(1/)
RMQ(const vector<T>& V) { "Polynomial.h" 23 lines C.resize(L + 1); C.erase(C.begin());
int N = sz(V), on = 1, depth = 1; vector<double> poly_roots(Poly p, double xmin, double xmax) { trav(x, C) x = (mod - x) % mod;
while (on < sz(V)) on *= 2, depth++; if (sz(p.a) == 2) { return {-p.a[0]/p.a[1]}; } return C;
jmp.assign(depth, V); vector<double> ret; }
rep(i,0,depth-1) rep(j,0,N) Poly der = p;
jmp[i+1][j] = min(jmp[i][j], der.diff();
jmp[i][min(N - 1, j + (1 << i))]); auto dr = poly_roots(der, xmin, xmax);
LinearRecurrence.h
} Description: Generates the k’th term of an n-order linear recurrence
dr.push_back(xmin-1); P
dr.push_back(xmax+1);
S[i] = j S[i − j − 1]tr[j], given S[0 . . . n − 1] and tr[0 . . . n − 1]. Faster than
T query(int a, int b) { sort(all(dr)); matrix multiplication. Useful together with Berlekamp–Massey.
assert(a < b); // or return i n f i f a == b rep(i,0,sz(dr)-1) { Usage: linearRec({0, 1}, {1, 1}, k) // k’th Fibonacci number
Time: O n2 log k
int dep = 31 - __builtin_clz(b - a); double l = dr[i], h = dr[i+1]; 26 lines
return min(jmp[dep][a], jmp[dep][b - (1 << dep)]); bool sign = p(l) > 0;
} typedef vector<ll> Poly;
if (sign ˆ (p(h) > 0)) { ll linearRec(Poly S, Poly tr, ll k) {
}; rep(it,0,60) { // while (h − l > 1e−8) int n = sz(S);
double m = (l + h) / 2, f = p(m);
if ((f <= 0) ˆ sign) l = m; auto combine = [&](Poly a, Poly b) {
Numerical (4) else h = m; Poly res(n * 2 + 1);
} rep(i,0,n+1) rep(j,0,n+1)
ret.push_back((l + h) / 2);
GoldenSectionSearch.h }
res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
Description: Finds the argument minimizing the function f in the inter- for (int i = 2 * n; i > n; --i) rep(j,0,n)
} res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
val [a, b] assuming f is unimodal on the interval, i.e. has only one local
return ret; res.resize(n + 1);
minimum. The maximum error in the result is eps. Works equally well for
} return res;
maximization with a small change in the code. See TernarySearch.h in the
Various chapter for a discrete version. };
Usage: double func(double x) { return 4+x+.3*x*x; } PolyInterpolate.h Poly pol(n + 1), e(pol);
double xmin = gss(-1000,1000,func); Description: Given n points (x[i], y[i]), computes an n-1-degree polynomial
Time: O (log((b − a)/)) pol[0] = e[1] = 1;
14 lines p that passes through them: p(x) = a[0] ∗ x0 + ... + a[n − 1] ∗ xn−1 . For
double gss(double a, double b, double (*f)(double)) { numerical precision, pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1.
for (++k; k; k /= 2) {
Time: O n2
double r = (sqrt(5)-1)/2, eps = 1e-7; 13 lines if (k % 2) pol = combine(pol, e);
double x1 = b - r*(b-a), x2 = a + r*(b-a); typedef vector<double> vd; e = combine(e, e);
double f1 = f(x1), f2 = f(x2); vd interpolate(vd x, vd y, int n) { }
while (b-a > eps) vd res(n), temp(n);
if (f1 < f2) { //change to > to find maximum rep(k,0,n-1) rep(i,k+1,n) ll res = 0;
b = x2; x2 = x1; f2 = f1; y[i] = (y[i] - y[k]) / (x[i] - x[k]); rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod;
x1 = b - r*(b-a); f1 = f(x1); double last = 0; temp[0] = 1; return res;
} else { rep(k,0,n) rep(i,0,n) { }
a = x1; x1 = x2; f1 = f2; res[i] += y[k] * temp[i];
x2 = a + r*(b-a); f2 = f(x2); swap(last, temp[i]);
} HillClimbing.h
temp[i] -= last * x[k]; Description: Poor man’s optimization for unimodal functions.
return a; } 16 lines
} return res; typedef array<double, 2> P;
}
Polynomial.h double func(P p);
17 lines
rep(i,0,n) { diag[i+1] -= super[i]*sub[i]/diag[i]; const ll mod = (119 << 23) + 1, root = 3; // = 998244353
KTH FastSubsetTransform ModularArithmetic ModInverse ModPow ModSum ModMulLL ModSqrt eratosthenes 8
// For p < 2ˆ30 there i s also e . g . (5 << 25, 3) , (7 << 26, 3) , 5.1 Modular arithmetic ModMulLL.h
// (479 << 21, 3) and (483 << 21, 5) . The l a s t two are > 10ˆ9. Description: Calculate a · b mod c (or ab mod c) for large c.
Time: O (64/bits · log b), where bits = 64 − k, if we want to deal with k-bit
typedef vector<ll> vl; ModularArithmetic.h numbers. 19 lines
void ntt(ll* x, ll* temp, ll* roots, int N, int skip) { Description: Operators for modular arithmetic. You need to set mod to
if (N == 1) return; typedef unsigned long long ull;
some number first and then you can use the structure. const int bits = 10;
int n2 = N/2; 18 lines
ntt(x , temp, roots, n2, skip*2);
"euclid.h" // i f a l l numbers are l e s s than 2ˆk , set b i t s = 64−k
ntt(x+skip, temp, roots, n2, skip*2); const ll mod = 17; // change to something e l s e const ull po = 1 << bits;
rep(i,0,N) temp[i] = x[i*skip]; struct Mod { ull mod_mul(ull a, ull b, ull &c) {
rep(i,0,n2) { ll x; ull x = a * (b & (po - 1)) % c;
ll s = temp[2*i], t = temp[2*i+1] * roots[skip*i]; Mod(ll xx) : x(xx) {} while ((b >>= bits) > 0) {
x[skip*i] = (s + t) % mod; x[skip*(i+n2)] = (s - t) % mod; Mod operator+(Mod b) { return Mod((x + b.x) % mod); } a = (a << bits) % c;
} Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod); } x += (a * (b & (po - 1))) % c;
} Mod operator*(Mod b) { return Mod((x * b.x) % mod); } }
void ntt(vl& x, bool inv = false) { Mod operator/(Mod b) { return *this * invert(b); } return x % c;
ll e = modpow(root, (mod-1) / sz(x)); Mod invert(Mod a) { }
if (inv) e = modpow(e, mod-2); ll x, y, g = euclid(a.x, mod, x, y); ull mod_pow(ull a, ull b, ull mod) {
vl roots(sz(x), 1), temp = roots; assert(g == 1); return Mod((x + mod) % mod); if (b == 0) return 1;
rep(i,1,sz(x)) roots[i] = roots[i-1] * e % mod; } ull res = mod_pow(a, b / 2, mod);
ntt(&x[0], &temp[0], &roots[0], sz(x), 1); Mod operatorˆ(ll e) { res = mod_mul(res, res, mod);
} if (!e) return Mod(1); if (b & 1) return mod_mul(res, a, mod);
vl conv(vl a, vl b) { Mod r = *this ˆ (e / 2); r = r * r; return res;
int s = sz(a) + sz(b) - 1; if (s <= 0) return {}; return e&1 ? *this * r : r; }
int L = s > 1 ? 32 - __builtin_clz(s - 1) : 0, n = 1 << L; }
};
if (s <= 200) { // ( factor 10 optimization for | a | , | b | = 10) ModSqrt.h
vl c(s); Description: Tonelli-Shanks algorithm for modular square roots.
Time: O log2 p worst case, often O (log p)
rep(i,0,sz(a)) rep(j,0,sz(b))
c[i + j] = (c[i + j] + a[i] * b[j]) % mod; ModInverse.h "ModPow.h" 24 lines
return c; Description: Pre-computation of modular inverses. Assumes LIM ≤ mod ll sqrt(ll a, ll p) {
} and that mod is a prime. a %= p; if (a < 0) a += p;
3 lines
a.resize(n); ntt(a); if (a == 0) return 0;
b.resize(n); ntt(b); const ll mod = 1000000007, LIM = 200000;
ll* inv = new ll[LIM] - 1; inv[1] = 1; assert(modpow(a, (p-1)/2, p) == 1);
vl c(n); ll d = modpow(n, mod-2); if (p % 4 == 3) return modpow(a, (p+1)/4, p);
rep(i,0,n) c[i] = a[i] * b[i] % mod * d % mod; rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[mod % i] % mod;
// aˆ(n+3)/8 or 2ˆ(n+3)/8 ∗ 2ˆ(n−1)/4 works i f p % 8 == 5
ntt(c, true); c.resize(s); return c; ll s = p - 1, n = 2;
} int r = 0, m;
ModPow.h 6 lines while (s % 2 == 0)
++r, s /= 2;
const ll mod = 1000000007; // f a s t e r i f const
while (modpow(n, (p - 1) / 2, p) != p - 1) ++n;
ll modpow(ll a, ll e) {
ll x = modpow(a, (s + 1) / 2, p);
FastSubsetTransform.h if (e == 0) return 1;
ll b = modpow(a, s, p), g = modpow(n, s, p);
Description: Transform to a basis with fast convolutions of the form ll x = modpow(a * a % mod, e >> 1);
for (;; r = m) {
X return e & 1 ? x * a % mod : x;
c[z] = a[x] · b[y], where ⊕ is one of AND, OR, XOR. The size }
ll t = b;
z=x⊕y
for (m = 0; m < r && t != 1; ++m)
of a must be a power of two.
t = t * t % p;
Time: O (N log N ) 16 lines if (m == 0) return x;
void FST(vi& a, bool inv) { ModSum.h ll gs = modpow(g, 1LL << (r - m - 1), p);
for (int n = sz(a), step = 1; step < n; step *= 2) { Description: Sums of mod’ed
Pto−1arithmetic progressions. g = gs * gs % p;
for (int i = 0; i < n; i += 2 * step) rep(j,i,i+step) { modsum(to, c, k, m) = i=0 (ki + c)%m. divsum is similar but for x = x * gs % p;
int &u = a[j], &v = a[j + step]; tie(u, v) = floored division. b = b * g % p;
inv ? pii(v - u, u) : pii(v, u + v); // AND Time: log(m), with a large constant. 16 lines }
inv ? pii(v, u - v) : pii(u + v, u); // OR }
typedef unsigned long long ull;
pii(u + v, u - v); // XOR ull sumsq(ull to) { return to / 2 * ((to-1) | 1); }
}
} ull divsum(ull to, ull c, ull k, ull m) {
5.2 Primality
if (inv) trav(x, a) x /= sz(a); // XOR only ull res = k / m * sumsq(to) + c / m * to;
} k %= m; c %= m; eratosthenes.h
vi conv(vi a, vi b) { if (!k) return res; Description: Prime sieve for generating all primes up to a certain limit.
FST(a, 0); FST(b, 0); ull to2 = (to * k + c) / m; isprime[i] is true iff i is a prime.
rep(i,0,sz(a)) a[i] *= b[i]; return res + (to - 1) * to2 - divsum(to2, m-1 - c, m, k); Time: lim=100’000’000 ≈ 0.8 s. Runs 30% faster if only odd indices are
FST(a, 1); return a; } stored.
} 11 lines
const int MAX_PR = 5’000’000;
ll modsum(ull to, ll c, ll k, ll m) {
bitset<MAX_PR> isprime;
c = ((c % m) + m) % m;
vi eratosthenes_sieve(int lim) {
k = ((k % m) + m) % m;
isprime.set(); isprime[0] = isprime[1] = 0;
return to * c + k * sumsq(to) - m * divsum(to, c, k, m);
for (int i = 4; i < lim; i += 2) isprime[i] = 0;
Number theory (5) }
for (int i = 3; i*i < lim; i += 2) if (isprime[i])
KTH MillerRabin factor euclid Euclid phiFunction ContinuedFractions FracBinarySearch 9
for (int j = i*i; j < lim; j += i*2) isprime[j] = 0; 5.3 Divisibility 5.4 Fractions
vi pr;
rep(i,2,lim) if (isprime[i]) pr.push_back(i);
return pr; euclid.h
} Description: Finds the Greatest Common Divisor to the integers a and b.
Euclid also finds two integers x and y, such that ax + by = gcd(a, b). If a
and b are coprime, then x is the inverse of a (mod b).
ContinuedFractions.h
7 lines Description: Given N and a real number x ≥ 0, finds the closest rational
MillerRabin.h ll gcd(ll a, ll b) { return __gcd(a, b); } approximation p/q with p, q ≤ N . It will obey |p/q − x| ≤ 1/qN .
Description: Deterministic Miller-Rabin primality test. Guaranteed to For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . (pk /qk alternates
work for numbers up to 264 ; for larger numbers, extend A randomly. ll euclid(ll a, ll b, ll &x, ll &y) { between > x and < x.) If x is rational, y eventually becomes ∞; if x is the
Time: 7 times the complexity of ab mod c. if (b) { ll d = euclid(b, a % b, y, x); root of a degree 2 polynomial the a’s eventually become cyclic.
"ModMulLL.h" 12 lines return y -= a/b * x, d; } Time: O (log N ) 21 lines
bool isPrime(ull n) { return x = 1, y = 0, a;
} typedef double d; // for N ∼ 1e7 ; long double for N ∼ 1e9
if (n < 2 || n % 6 % 4 != 1) return n - 2 < 2;
pair<ll, ll> approximate(d x, ll N) {
ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; d y = x;
s = __builtin_ctzll(n-1), d = n >> s;
trav(a, A) { // ˆ count t r a i l i n g zeroes Euclid.java for (;;) {
ull p = mod_pow(a, d, n), i = s; Description: Finds {x, y, d} s.t. ax + by = d = gcd(a, b). 11 lines
ll lim = min(P ? (N-LP) / P : inf, Q ? (N-LQ) / Q : inf),
a = (ll)floor(y), b = min(a, lim),
while (p != 1 && p != n - 1 && a % n && i--) static BigInteger[] euclid(BigInteger a, BigInteger b) { NP = b*P + LP, NQ = b*Q + LQ;
p = mod_mul(p, p, n); BigInteger x = BigInteger.ONE, yy = x; if (a > b) {
if (p != n-1 && i != s) return 0; BigInteger y = BigInteger.ZERO, xx = y; // I f b > a/2, we have a semi−convergent that gives us a
} while (b.signum() != 0) { // better approximation ; i f b = a/2, we ∗may∗ have one .
return 1; BigInteger q = a.divide(b), t = b; // Return {P, Q} here for a more canonical approximation .
} b = a.mod(b); a = t; return (abs(x - (d)NP / (d)NQ) < abs(x - (d)P / (d)Q)) ?
t = xx; xx = x.subtract(q.multiply(xx)); x = t; make_pair(NP, NQ) : make_pair(P, Q);
t = yy; yy = y.subtract(q.multiply(yy)); y = t; }
factor.h } if (abs(y = 1/(y - (d)a)) > 3*N) {
Description: Pollard’s rho algorithm. It is a probabilistic factorisation al- return new BigInteger[]{x, y, a}; return {NP, NQ};
gorithm, whose expected time complexity is good. Before you start using it, } }
run init(bits), where bits is the length of the numbers you use. Returns LP = P; P = NP;
factors of the input without duplicates. LQ = Q; Q = NQ;
Time: Expected running time should be good enough for 50-bit numbers. 5.3.1 Bézout’s identity }
"ModMulLL.h", "MillerRabin.h", "eratosthenes.h" 35 lines
}
vector<ull> pr; For a 6=, b 6= 0, then d = gcd(a, b) is the smallest positive
ull f(ull a, ull n, ull &has) {
return (mod_mul(a, a, n) + has) % n; integer for which there are integer solutions to
}
vector<ull> factor(ull d) { FracBinarySearch.h
vector<ull> res; ax + by = d
Description: Given f and N , finds the smallest fraction p/q ∈ [0, 1] such
for (int i = 0; i < sz(pr) && pr[i]*pr[i] <= d; i++) that f (p/q) is true, and p, q ≤ N . You may want to throw an exception from
if (d % pr[i] == 0) { f if it finds an exact solution, in which case N can be removed.
while (d % pr[i] == 0) d /= pr[i]; If (x, y) is one solution, then all solutions are given by
Usage: fracBS([](Frac f) { return f.p>=3*f.q; }, 10); // {1,3}
res.push_back(pr[i]); Time: O (log(N ))
} 24 lines
}
} }
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 DelaunayTriangulation 19
PointInsideHull.h hi = mid; bool on_x(const P& a, const P& b) { return a.x < b.x; }
Description: Determine whether a point t lies inside a given polygon else lo = mid; bool on_y(const P& a, const P& b) { return a.y < b.y; }
(counter-clockwise order). The polygon must be such that every point on }
the circumference is visible from the first point in the vector. It returns 0 return a[hi%N].second; struct Node {
for points outside, 1 for points on the circumference, and 2 for points inside. } P pt; // i f t h i s i s a leaf , the single point in i t
Time: O (log N ) T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; // bounds
"Point.h", "sideOf.h", "onSegment.h" 22 lines bool isign(P a, P b, int x, int y, int s) { Node *first = 0, *second = 0;
typedef Point<ll> P; return sgn(a.cross(p[x], b)) * sgn(a.cross(p[y], b)) == s;
int insideHull2(const vector<P>& H, int L, int R, const P& p) { } T distance(const P& p) { // min squared distance to a point
int len = R - L; T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x);
if (len == 2) { int bs2(int lo, int hi, P a, P b) { T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y);
int sa = sideOf(H[0], H[L], p); int L = lo; return (P(x,y) - p).dist2();
int sb = sideOf(H[L], H[L+1], p); if (hi < lo) hi += N; }
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; Node(vector<P>&& vp) : pt(vp[0]) {
if (sb==0 || (sa==0 && L == 1) || (sc == 0 && R == sz(H))) if (isign(a, b, mid, L, -1)) hi = mid; for (P p : vp) {
return 1; else lo = mid; x0 = min(x0, p.x); x1 = max(x1, p.x);
return 2; } y0 = min(y0, p.y); y1 = max(y1, p.y);
} return lo; }
int mid = L + len / 2; } if (vp.size() > 1) {
if (sideOf(H[0], H[mid], p) >= 0) // s p l i t on x i f the box i s wider than high (not best
return insideHull2(H, mid, R, p); pii isct(P a, P b) { heuristic . . . )
return insideHull2(H, L, mid+1, p); int f = bs(a - b), j = bs(b - a); sort(all(vp), x1 - x0 >= y1 - y0 ? on_x : on_y);
} if (isign(a, b, f, j, 1)) return {-1, -1}; // divide by taking h a l f the array for each child (not
int x = bs2(f, j, a, b)%N, // best performance with many duplicates in the middle)
int insideHull(const vector<P>& hull, const P& p) { y = bs2(j, f, a, b)%N; int half = sz(vp)/2;
if (sz(hull) < 3) return onSegment(hull[0], hull.back(), p); if (a.cross(p[x], b) == 0 && first = new Node({vp.begin(), vp.begin() + half});
else return insideHull2(hull, 1, sz(hull), p); a.cross(p[x+1], b) == 0) return {x, x}; second = new Node({vp.begin() + half, vp.end()});
} if (a.cross(p[y], b) == 0 && }
a.cross(p[y+1], b) == 0) return {y, y}; }
if (a.cross(p[f], b) == 0) return {f, -1}; };
LineHullIntersection.h if (a.cross(p[j], b) == 0) return {j, -1};
Description: Line-convex polygon intersection. The polygon must be ccw return {x, y}; struct KDTree {
and have no colinear points. isct(a, b) returns a pair describing the inter- } Node* root;
section of a line with the polygon: • (−1, −1) if no collision, • (i, −1) if }; KDTree(const vector<P>& vp) : root(new Node({all(vp)})) {}
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 pair<T, P> search(Node *node, const P& p) {
as happening on side (i, i + 1). The points are returned in the same order as 8.4 Misc. Point Set Problems if (!node->first) {
the line hits the polygon. // uncomment i f we should not find the point i t s e l f :
Time: O (N + Q log n) // i f (p == node−>pt ) return {INF, P() };
ClosestPair.h return make_pair((p - node->pt).dist2(), node->pt);
"Point.h" 63 lines Description: Finds the closest pair of points.
}
ll sgn(ll a) { return (a > 0) - (a < 0); } Time: O (n log n)
typedef Point<ll> P; "Point.h" 17 lines
Node *f = node->first, *s = node->second;
struct HullIntersection { typedef Point<ll> P; T bfirst = f->distance(p), bsec = s->distance(p);
int N; pair<P, P> closest(vector<P> v) { if (bfirst > bsec) swap(bsec, bfirst), swap(f, s);
vector<P> p; assert(sz(v) > 1);
vector<pair<P, int>> a; set<P> S; // search c l o s e s t side f i r s t , other side i f needed
sort(all(v), [](P a, P b) { return a.y < b.y; }); auto best = search(f, p);
HullIntersection(const vector<P>& ps) : N(sz(ps)), p(ps) { pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P()}}; if (bsec < best.first)
p.insert(p.end(), all(ps)); int j = 0; best = min(best, search(s, p));
int b = 0; trav(p, v) { return best;
rep(i,1,N) if (P{p[i].y,p[i].x} < P{p[b].y, p[b].x}) b = i; P d{1 + (ll)sqrt(ret.first), 0}; }
rep(i,0,N) { while (v[j].y <= p.y - d.x) S.erase(v[j++]);
int f = (i + b) % N; auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d); // find nearest point to a point , and i t s squared distance
a.emplace_back(p[f+1] - p[f], f); for (; lo != hi; ++lo) // ( requires an arbitrary operator< for Point)
} ret = min(ret, {(*lo - p).dist2(), {*lo, p}}); pair<T, P> nearest(const P& p) {
} S.insert(p); return search(root, p);
} }
int qd(P p) { return ret.second; };
return (p.y < 0) ? (p.x >= 0) + 2 }
: (p.x <= 0) * (1 + (p.y <= 0));
}
kdTree.h DelaunayTriangulation.h
int bs(P dir) { Description: KD-tree (2d, can be extended to 3d) Description: Computes the Delaunay triangulation of a set of points. Each
int lo = -1, hi = N; "Point.h" 63 lines circumcircle contains none of the input points. If any three points are colin-
while (hi - lo > 1) { typedef long long T; ear or any four
are on the same circle, behavior is undefined.
int mid = (lo + hi) / 2; typedef Point<T> P; Time: O n2
if (make_pair(qd(dir), dir.y * a[mid].first.x) < const T INF = numeric_limits<T>::max(); "Point.h", "3dHull.h" 10 lines