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

Kactl

The document contains code and descriptions related to various data structures and algorithms, including Link-Cut Trees, polynomial operations, and numerical methods. It features implementations for dynamic programming and mathematical computations, such as polynomial root finding and linear recurrence relations. The document also includes templates and configuration files for compiling and running the code efficiently.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
50 views26 pages

Kactl

The document contains code and descriptions related to various data structures and algorithms, including Link-Cut Trees, polynomial operations, and numerical methods. It features implementations for dynamic programming and mathematical computations, such as polynomial root finding and linear recurrence relations. The document also includes templates and configuration files for compiling and running the code efficiently.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

Massachusetts Institute of Technology

MIT NULL
Andrew He, Kevin Sun, Yinzhan Xu

adapted from KTH ACM Contest Template Library


2019-04-26
MIT NULL template hash hash-cpp Makefile vimrc nanorc LCT LineContainer 1
Contest (1) map gA m’ggVG"+y’’
}
}else rotate(x, t1);

com -range=% -nargs=1 P exe "<line1>,<line2>!".<q-args> |y| update(x);


template.cpp 15 lines ,→sil u|echom @" } // hash-cpp-2 = 0bc1a3b77275f92cebc947211444fdb7
#include <bits/stdc++.h> com -range=% Hash <line1>,<line2>P tr -d ’[:space:]’ |
using namespace std; ,→md5sum void access(T *x) { // hash-cpp-3
au FileType cpp com! -buffer -range=% Hash <line1>,<line2>P splay(x);
#define rep(i, a, b) for(int i = a; i < (b); ++i) ,→ cpp -dD -P -fpreprocessed | tr -d ’[:space:]’ | x -> son[1] -> pf = x;
#define trav(a, x) for(auto& a : x) ,→md5sum x -> son[1] -> fa = null;
#define all(x) x.begin(), x.end() x -> son[1] = null;
#define sz(x) (int)(x).size() update(x);
typedef long long ll; nanorc 3 lines while (x -> pf != null) {
typedef pair<int, int> pii; set tabsize 4 splay(x -> pf);
typedef vector<int> vi; set const x -> pf -> son[1] -> pf = x -> pf;
set autoindent x -> pf -> son[1] -> fa = null;
int main() { x -> pf -> son[1] = x;
cin.sync_with_stdio(0); cin.tie(0); x -> fa = x -> pf;
cin.exceptions(cin.failbit); splay(x);
} Data structures (2) }
x -> rr = true;
LCT.cpp } // hash-cpp-3 = db89159f01a2099d67e93163c3bfa384
hash.sh 1 lines
Description: Link-Cut Tree. 106 lines
tr -d ’[:space:]’ | md5sum bool Cut(T *x, T *y) { // hash-cpp-4
struct T { access(x);
bool rr; access(y);
hash-cpp.sh 1 lines T *son[2], *pf, *fa; downdate(y);
} f1[N], *ff = f1, *f[N], *null; downdate(x);
cpp -dD -P -fpreprocessed | tr -d ’[:space:]’ | md5sum
if (y -> son[1] != x || x -> son[0] != null)
void downdate(T *x) { return false;
Makefile 25 lines
if (x -> rr) { y -> son[1] = null;
x -> son[0] -> rr = !x -> son[0] -> rr; x -> fa = x -> pf = null;
CXX = g++ x -> son[1] -> rr = !x -> son[1] -> rr; update(x);
CXXFLAGS = -O2 -std=gnu++14 -Wall -Wextra -Wno-unused- swap(x -> son[0], x -> son[1]); update(y);
,→result -pedantic -Wshadow -Wformat=2 -Wfloat-equal - x -> rr = false; return true;
,→Wconversion -Wlogical-op -Wshift-overflow=2 - } } // hash-cpp-4 = 42850d63565f84698378e8c2c23df1fe
,→Wduplicated-cond -Wcast-qual -Wcast-align // add stuff
# pause:#pragma GCC diagnostic {ignored|warning} "-Wshadow" } bool Connected(T *x, T *y) {
DEBUGFLAGS = -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC - access(x);
,→fsanitize=address -fsanitize=undefined -fno-sanitize- void update(T *x) { access(y);
,→recover=all -fstack-protector -D_FORTIFY_SOURCE=2 // add stuff return x == y || x -> fa != null;
CXXFLAGS += $(DEBUGFLAGS) # flags with speed penalty } }
TARGET := $(notdir $(CURDIR))
EXECUTE := ./$(TARGET) void rotate(T *x, bool t) { // hash-cpp-1 bool Link(T *x, T *y) {
CASES := $(sort $(basename $(wildcard *.in))) T *y = x -> fa, *z = y -> fa; if (Connected(x, y))
TESTS := $(sort $(basename $(wildcard *.out))) if (z != null) z -> son[z -> son[1] == y] = x; return false;
all: $(TARGET) x -> fa = z; access(x);
clean: y -> son[t] = x -> son[!t]; access(y);
-rm -rf $(TARGET) *.res x -> son[!t] -> fa = y; x -> pf = y;
%: %.cpp x -> son[!t] = y; return true;
$(LINK.cpp) $< $(LOADLIBES) $(LDLIBS) -o $@ y -> fa = x; }
run: $(TARGET) update(y);
time $(EXECUTE) } // hash-cpp-1 = 28958e1067126a5892dcaa67307d2f1d int main() {
%.res: $(TARGET) %.in read(n); read(m); read(q);
time $(EXECUTE) < $*.in > $*.res void xiao(T *x) { null = new T; null -> son[0] = null -> son[1] = null ->
%.out: % if (x -> fa != null) xiao(x -> fa), x -> pf = x -> fa -> ,→fa = null -> pf = null;
test_%: %.res %.out ,→ pf; for (int i = 1; i <= n; i++) {
diff $*.res $*.out downdate(x); f[i] = ++ff;
runs: $(patsubst %,%.res,$(CASES)) } f[i] -> son[0] = f[i] -> son[1] = f[i] -> fa = f[i] ->
test: $(patsubst %,test_%,$(TESTS)) ,→pf = null;
.PHONY: all clean run test test_% runs void splay(T *x) { // hash-cpp-2 f[i] -> rr = false;
.PRECIOUS: %.res xiao(x); }
T *y, *z; // init null and f[i]
vimrc while (x -> fa != null) { }
8 lines y = x -> fa; z = y -> fa;
set nocp ai bs=2 hls ic is lbr ls=2 mouse=a nu ru sc scs bool t1 = (y -> son[1] == x), t2 = (z -> son[1] == y);
,→smd so=3 sw=4 ts=4 if (z != null) {
filetype plugin indent on if (t1 == t2) rotate(y, t2), rotate(x, t1);
syn on else rotate(x, t1), rotate(x, t2);
MIT NULL GoldenSectionSearch Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence 2
LineContainer.h Polynomial.h 17 lines
}
Description: Container where you can add lines of the form kx+m, and return res;
query maximum values at points x. Useful for dynamic programming. struct Poly { } // hash-cpp-all = 08bf48c9301c849dfc6064b6450af6f3
Time: O (log N ) vector<double> a;
32 lines double operator()(double x) const {
bool Q; double val = 0; BerlekampMassey.h
struct Line { for(int i = sz(a); i--;) (val *= x) += a[i]; Description: Recovers any n-order linear recurrence relation from the
mutable ll k, m, p; return val; first 2n terms of the recurrence. Useful for guessing linear recurrences
bool operator<(const Line& o) const { } after brute-forcing the first terms. Should work on any field, but nu-
return Q ? p < o.p : k < o.k; void diff() { merical stability for floats is not guaranteed. Output will have size ≤ n.
} rep(i,1,sz(a)) a[i-1] = i*a[i]; Usage: BerlekampMassey({0, 1, 1, 3, 5, 11}) // {1, 2}
}; a.pop_back(); "../number-theory/ModPow.h" 20 lines
}
struct LineContainer : multiset<Line> { void divroot(double x0) { vector<ll> BerlekampMassey(vector<ll> s) {
// (for doubles, use inf = 1/.0, div(a,b) = a/b) double b = a.back(), c; a.back() = 0; int n = sz(s), L = 0, m = 0;
const ll inf = LLONG_MAX; for(int i=sz(a)-1; i--;) c = a[i], a[i] = a[i+1]*x0+b, vector<ll> C(n), B(n), T;
ll div(ll a, ll b) { // floored division ,→b=c; C[0] = B[0] = 1;
return a / b - ((a ˆ b) < 0 && a % b); } a.pop_back();
bool isect(iterator x, iterator y) { } ll b = 1;
if (y == end()) { x->p = inf; return false; } }; // hash-cpp-all = c9b7b07a5aae7b0a6df1b8cdb046375f rep(i,0,n) { ++m;
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; ll d = s[i] % mod;
else x->p = div(y->m - x->m, x->k - y->k); rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
return x->p >= y->p; PolyRoots.h if (!d) continue;
} Description: Finds the real roots to a polynomial. T = C; ll coef = d * modpow(b, mod-2) % mod;
void add(ll k, ll m) { Usage: poly roots({{2,-3,1}},-1e9,1e9) // solve xˆ2-3x+2 = 0 rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
Time: O n2 log(1/)

auto z = insert({k, m, 0}), y = z++, x = y; if (2 * L > i) continue;
while (isect(y, z)) z = erase(z); "Polynomial.h" 23 lines L = i + 1 - L; B = T; b = d; m = 0;
if (x != begin() && isect(--x, y)) isect(x, y = erase(y vector<double> poly_roots(Poly p, double xmin, double xmax) }
,→)); ,→ {
while ((y = x) != begin() && (--x)->p >= y->p) if (sz(p.a) == 2) { return {-p.a[0]/p.a[1]}; } C.resize(L + 1); C.erase(C.begin());
isect(x, erase(y)); vector<double> ret; trav(x, C) x = (mod - x) % mod;
} Poly der = p; return C;
ll query(ll x) { der.diff(); } // hash-cpp-all = 40387d9fed31766a705d6b2206790deb
assert(!empty()); auto dr = poly_roots(der, xmin, xmax);
Q = 1; auto l = *lower_bound({0,0,x}); Q = 0; dr.push_back(xmin-1);
return l.k * x + l.m; dr.push_back(xmax+1); LinearRecurrence.h
} sort(all(dr)); Description:
P Generates the k’th term of an n-order linear recurrence
}; // hash-cpp-all = 1a3c15147b3a3e2ea69bfa41ac9f0914 rep(i,0,sz(dr)-1) { S[i] = j S[i − j − 1]tr[j], given S[0 . . . n − 1] and tr[0 . . . n − 1]. Faster
double l = dr[i], h = dr[i+1]; than matrix multiplication. Useful together with Berlekamp–Massey.
bool sign = p(l) > 0; Usage: linearRec({0, 1}, {1, 1}, k) // k’th Fibonacci
if (sign ˆ (p(h) > 0)) { number
Numerical (3) 2

rep(it,0,60) { // while (h - l > 1e-8) Time: O n log k 26 lines
double m = (l + h) / 2, f = p(m);
typedef vector<ll> Poly;
if ((f <= 0) ˆ sign) l = m;
ll linearRec(Poly S, Poly tr, ll k) { // hash-cpp-1
GoldenSectionSearch.h else h = m;
int n = sz(S);
Description: Finds the argument minimizing the function f in the in- }
terval [a, b] assuming f is unimodal on the interval, i.e. has only one ret.push_back((l + h) / 2);
auto combine = [&](Poly a, Poly b) {
local minimum. The maximum error in the result is eps. Works equally }
Poly res(n * 2 + 1);
well for maximization with a small change in the code. See Ternary- }
rep(i,0,n+1) rep(j,0,n+1)
Search.h in the Various chapter for a discrete version. return ret;
res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
Usage: double func(double x) { return 4+x+.3*x*x; } } // hash-cpp-all = 2cf1903cf3e930ecc5ea0059a9b7fce5
for (int i = 2 * n; i > n; --i) rep(j,0,n)
double xmin = gss(-1000,1000,func); res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) %
Time: O (log((b − a)/)) 14 lines PolyInterpolate.h ,→mod;
Description: Given n points (x[i], y[i]), computes an n-1-degree poly- res.resize(n + 1);
double gss(double a, double b, double (*f)(double)) {
nomial p that passes through them: p(x) = a[0]∗x0 +...+a[n−1]∗xn−1 . return res;
double r = (sqrt(5)-1)/2, eps = 1e-7;
For numericalprecision, pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1. };
double x1 = b - r*(b-a), x2 = a + r*(b-a);
double f1 = f(x1), f2 = f(x2); Time: O n2 13 lines Poly pol(n + 1), e(pol);
while (b-a > eps)
typedef vector<double> vd; pol[0] = e[1] = 1;
if (f1 < f2) { //change to > to find maximum
vd interpolate(vd x, vd y, int n) {
b = x2; x2 = x1; f2 = f1;
vd res(n), temp(n); for (++k; k; k /= 2) {
x1 = b - r*(b-a); f1 = f(x1);
rep(k,0,n-1) rep(i,k+1,n) if (k % 2) pol = combine(pol, e);
} else {
y[i] = (y[i] - y[k]) / (x[i] - x[k]); e = combine(e, e);
a = x1; x1 = x2; f1 = f2;
double last = 0; temp[0] = 1; }
x2 = a + r*(b-a); f2 = f(x2);
rep(k,0,n) rep(i,0,n) {
}
res[i] += y[k] * temp[i]; ll res = 0;
return a;
swap(last, temp[i]); rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod;
} // hash-cpp-all = 31d45b514727a298955001a74bb9b9fa
temp[i] -= last * x[k]; return res;
MIT NULL Integrate IntegrateAdaptive Determinant IntDeterminant Simplex math-simplex 3
} // hash-cpp-1 = 261dd85251df2df60ee444e087e8ffc2 const ll mod = 12345; D[r][s] = inv;
ll det(vector<vector<ll>>& a) { swap(B[r], N[s]);
int n = sz(a); ll ans = 1; } // hash-cpp-2 = 9cd0a84b89fb678b2888e0defa688de2
Integrate.h rep(i,0,n) {
Description: Simple integration of a function over an interval using
rep(j,i+1,n) { bool simplex(int phase) { // hash-cpp-3
Simpson’s rule. The error should be proportional to h4 , although in
while (a[j][i] != 0) { // gcd step int x = m + phase - 1;
practice you will want to verify that the result is stable to desired pre-
ll t = a[i][i] / a[j][i]; for (;;) {
cision when epsilon changes. 8 lines if (t) rep(k,i,n) int s = -1;
double quad(double (*f)(double), double a, double b) { a[i][k] = (a[i][k] - a[j][k] * t) % mod; rep(j,0,n+1) if (N[j] != -phase) ltj(D[x]);
const int n = 1000; swap(a[i], a[j]); if (D[x][s] >= -eps) return true;
double h = (b - a) / 2 / n; ans *= -1; int r = -1;
double v = f(a) + f(b); } rep(i,0,m) {
rep(i,1,n*2) } if (D[i][s] <= eps) continue;
v += f(a + i*h) * (i&1 ? 4 : 2); ans = ans * a[i][i] % mod; if (r == -1 || MP(D[i][n+1] / D[i][s], B[i])
return v * h / 3; if (!ans) return 0; < MP(D[r][n+1] / D[r][s], B[r])) r = i
} // hash-cpp-all = 65e2375b3152c23048b469eb414fe6b6 } ,→;
return (ans + mod) % mod; }
} // hash-cpp-all = 3313dc3b38059fdf9f41220b469cfd13 if (r == -1) return false;
IntegrateAdaptive.h pivot(r, s);
Description: Fast integration using an adaptive Simpson’s rule. }
Usage: double z, y; } // hash-cpp-3 = f156440bce4f5370ea43b0efa7de25ed
double h(double x) { return x*x + y*y + z*z <= 1; } Simplex.h
double g(double y) { ::y = y; return quad(h, -1, 1); } Description: Solves a general linear maximization problem: maximize
cT x subject to Ax ≤ b, x ≥ 0. Returns -inf if there is no solution, inf T solve(vd &x) { // hash-cpp-4
double f(double z) { ::z = z; return quad(g, -1, 1); } int r = 0;
double sphereVol = quad(f, -1, 1), pi = sphereVol*3/4;16 if there are arbitrarily good solutions, or the maximum value of cT x
lines otherwise. The input vector is set to an optimal x (or in the unbounded rep(i,1,m) if (D[i][n+1] < D[r][n+1]) r = i;
typedef double d; case, an arbitrary solution fulfilling the constraints). Numerical stabil- if (D[r][n+1] < -eps) {
d simpson(d (*f)(d), d a, d b) { ity is not guaranteed. For better performance, define variables such that pivot(r, n);
d c = (a+b) / 2; x = 0 is viable. if (!simplex(2) || D[m+1][n+1] < -eps) return -inf;
return (f(a) + 4*f(c) + f(b)) * (b-a) / 6; Usage: vvd A = {{1,-1}, {-1,1}, {-1,-2}}; rep(i,0,m) if (B[i] == -1) {
} vd b = {1,1,-4}, c = {-1,-1}, x; int s = 0;
d rec(d (*f)(d), d a, d b, d eps, d S) { T val = LPSolver(A, b, c).solve(x); rep(j,1,n+1) ltj(D[i]);
d c = (a+b) / 2; Time: O (N M ∗ #pivots), where a pivot may be e.g. an edge relax- pivot(i, s);
d S1 = simpson(f, a, c); ation. O (2n ) in the general case. }
68 lines }
d S2 = simpson(f, c, b), T = S1 + S2;
if (abs (T - S) <= 15*eps || b-a < 1e-10) typedef double T; // long double, Rational, double + mod<P bool ok = simplex(1); x = vd(n);
return T + (T - S) / 15; ,→>... rep(i,0,m) if (B[i] < n) x[B[i]] = D[i][n+1];
return rec(f, a, c, eps/2, S1) + rec(f, c, b, eps/2, S2); typedef vector<T> vd; return ok ? D[m][n+1] : inf;
} typedef vector<vd> vvd; } // hash-cpp-4 = 396a95621f5e196bb87eb95518560dfb
d quad(d (*f)(d), d a, d b, d eps = 1e-8) { };
return rec(f, a, b, eps, simpson(f, a, b)); const T eps = 1e-8, inf = 1/.0;
} // hash-cpp-all = ad8a754372ce74e5a3d07ce46c2fe0ca #define MP make_pair
#define ltj(X) if(s == -1 || MP(X[j],N[j]) < MP(X[s],N[s])) math-simplex.cpp
,→ s=j Description: Simplex algorithm. WARNING- segfaults on empty (size
Determinant.h 0) max cx st Ax<=b, x>=0 do 2 phases; 1st check feasibility; 2nd check
Description: Calculates determinant of a matrix. Destroys the matrix. struct LPSolver { boundedness and ans
Time: O N 3 15 lines int m, n; 40 lines
vi N, B; vector<double> simplex(vector<vector<double> > A, vector<
double det(vector<vector<double>>& a) {
vvd D; ,→double> b, vector<double> c) {
int n = sz(a); double res = 1;
int n = (int) A.size(), m = (int) A[0].size()+1, r = n, s
rep(i,0,n) {
LPSolver(const vvd& A, const vd& b, const vd& c) : ,→ = m-1;
int b = i;
m(sz(b)), n(sz(c)), N(n+1), B(m), D(m+2, vd(n+2)) { // vector<vector<double> > D = vector<vector<double> > (n+2,
rep(j,i+1,n) if (fabs(a[j][i]) > fabs(a[b][i])) b = j;
,→hash-cpp-1 ,→ vector<double>(m+1));
if (i != b) swap(a[i], a[b]), res *= -1;
rep(i,0,m) rep(j,0,n) D[i][j] = A[i][j]; vector<int> ix = vector<int> (n+m);
res *= a[i][i];
rep(i,0,m) { B[i] = n+i; D[i][n] = -1; D[i][n+1] = b[ for (int i=0; i<n+m; i++) ix[i] = i;
if (res == 0) return 0;
,→i];} for (int i=0; i<n; i++) {
rep(j,i+1,n) {
rep(j,0,n) { N[j] = j; D[m][j] = -c[j]; } for (int j=0; j<m-1; j++)D[i][j]=-A[i][j];
double v = a[j][i] / a[i][i];
N[n] = -1; D[m+1][n] = 1; D[i][m-1] = 1;
if (v != 0) rep(k,i+1,n) a[j][k] -= v * a[i][k];
} // hash-cpp-1 = 6ff8e92a6bb47fbd6606c75a07178914 D[i][m] = b[i];
}
if (D[r][m] > D[i][m]) r = i;
}
void pivot(int r, int s) { // hash-cpp-2 }
return res;
T *a = D[r].data(), inv = 1 / a[s]; for (int j=0; j<m-1; j++) D[n][j]=c[j];
} // hash-cpp-all = bd5cec161e6ad4c483e662c34eae2d08
rep(i,0,m+2) if (i != r && abs(D[i][s]) > eps) { D[n+1][m-1] = -1; int z = 0;
T *b = D[i].data(), inv2 = b[s] * inv; for (double d;;) {
IntDeterminant.h rep(j,0,n+2) b[j] -= a[j] * inv2; if (r < n) {
Description: Calculates determinant using modular arithmetics. Mod- b[s] = a[s] * inv2; swap(ix[s], ix[r+m]);
ulos can also be
 removed to get a pure-integer version. } D[r][s] = 1.0/D[r][s];
Time: O N 3 18 lines
rep(j,0,n+2) if (j != s) D[r][j] *= inv; for (int j=0; j<=m; j++) if (j!=s) D[r][j] *= -D[r][s
rep(i,0,m+2) if (i != r) D[i][s] *= -inv; ,→];
MIT NULL SolveLinear SolveLinear2 SolveLinearBinary MatrixInverse Tridiagonal 4
3

for(int i=0; i<=n+1; i++)if(i!=r) { x[col[i]] = b[i]; Time: O n 35 lines
for (int j=0; j<=m; j++) if(j!=s) D[i][j] += D[r][j rep(j,0,i) b[j] -= A[j][i] * b[i];
,→] * D[i][s]; } int matInv(vector<vector<double>>& A) {
D[i][s] *= D[r][s]; return rank; // (multiple solutions if rank < m) int n = sz(A); vi col(n);
} } // hash-cpp-all = 44c9ab90319b30df6719c5b5394bc618 vector<vector<double>> tmp(n, vector<double>(n));
} rep(i,0,n) tmp[i][i] = 1, col[i] = i;
r = -1; s = -1;
for (int j=0; j <m; j++) if (s<0 || ix[s]>ix[j]) { SolveLinear2.h rep(i,0,n) {
if (D[n+1][j]>eps || D[n+1][j]>-eps && D[n][j]>eps) s Description: To get all uniquely determined values of x back from int r = i, c = i;
,→ = j; SolveLinear, make the following changes: rep(j,i,n) rep(k,i,n)
} "SolveLinear.h" 8 lines
if (fabs(A[j][k]) > fabs(A[r][c]))
if (s < 0) break; r = j, c = k;
rep(j,0,n) if (j != i) // instead of rep(j,i+1,n) if (fabs(A[r][c]) < 1e-12) return i;
for (int i=0; i<n; i++) if(D[i][s]<-eps) { // ... then at the end:
if (r < 0 || (d = D[r][m]/D[r][s]-D[i][m]/D[i][s]) < A[i].swap(A[r]); tmp[i].swap(tmp[r]);
x.assign(m, undefined); rep(j,0,n)
,→-eps rep(i,0,rank) {
|| d < eps && ix[r+m] > ix[i+m]) r=i; swap(A[j][i], A[j][c]), swap(tmp[j][i], tmp[j][c]);
rep(j,rank,m) if (fabs(A[i][j]) > eps) goto fail; swap(col[i], col[c]);
} x[col[i]] = b[i] / A[i][i];
if (r < 0) return vector<double>(); // unbounded double v = A[i][i];
fail:; } rep(j,i+1,n) {
} // hash-cpp-all = 08e495d9d51e80a183ccd030e3bf6700
if (D[n+1][m] < -eps) return vector<double>(); // double f = A[j][i] / v;
,→infeasible A[j][i] = 0;
rep(k,i+1,n) A[j][k] -= f*A[i][k];
vector<double> x(m-1); SolveLinearBinary.h rep(k,0,n) tmp[j][k] -= f*tmp[i][k];
for (int i = m; i < n+m; i ++) if (ix[i] < m-1) x[ix[i]] Description: Solves Ax = b over F2 . If there are multiple solutions,
,→= D[i-m][m]; }
one is returned arbitrarily. Returns rank, or -1 if no solutions. Destroys
printf("%.2lf\n", D[n][m]); rep(j,i+1,n) A[i][j] /= v;
A and b.
rep(j,0,n) tmp[i][j] /= v;
Time: O n2 m

return x; // ans: D[n][m]
} // hash-cpp-all = 70201709abdff05eff90d9393c756b95
34 lines A[i][i] = 1;
typedef bitset<1000> bs; }

int solveLinear(vector<bs>& A, vi& b, bs& x, int m) { for (int i = n-1; i > 0; --i) rep(j,0,i) {
SolveLinear.h int n = sz(A), rank = 0, br; double v = A[j][i];
Description: Solves A ∗ x = b. If there are multiple solutions, an ar- assert(m <= sz(x)); rep(k,0,n) tmp[j][k] -= v*tmp[i][k];
bitrary one is returned. Returns rank, or -1 if no solutions. Data in A vi col(m); iota(all(col), 0); }
and b is lost.  rep(i,0,n) {
Time: O n2 m 38 lines for (br=i; br<n; ++br) if (A[br].any()) break; rep(i,0,n) rep(j,0,n) A[col[i]][col[j]] = tmp[i][j];
typedef vector<double> vd; if (br == n) { return n;
const double eps = 1e-12; rep(j,i,n) if(b[j]) return -1; } // hash-cpp-all = ebfff64122d6372fde3a086c95e2cfc7
break;
int solveLinear(vector<vd>& A, vd& b, vd& x) { } Tridiagonal.h
int n = sz(A), m = sz(x), rank = 0, br, bc; int bc = (int)A[br]._Find_next(i-1); Description: x = tridiagonal(d, p, q, b) solves the equation system
if (n) assert(sz(A[0]) == m); swap(A[i], A[br]);
vi col(m); iota(all(col), 0); swap(b[i], b[br]);
b0 d0 p0 0 0 ··· 0 x0
    
swap(col[i], col[bc]);
b1  q0 d1 p1 0 ··· 0 x1
rep(j,0,n) if (A[j][i] != A[j][bc]) {
   
rep(i,0,n) {  b2   0 q1 d2 p2 ··· 0  x2 
double v, bv = 0; A[j].flip(i); A[j].flip(bc);     
 b3 = .
 
. .. .. .. .
 x3 .

rep(r,i,n) rep(c,i,m) } 
 . . .


.

 . . . . . .

.

if ((v = fabs(A[r][c])) > bv) rep(j,i+1,n) if (A[j][i]) { 
.
 
.

b[j] ˆ= b[i];
 .   0 0 ··· qn−3 dn−2 pn−2  . 
br = r, bc = c, bv = v; bn−1 0 0 ··· 0 qn−2 dn−1 xn−1
if (bv <= eps) { A[j] ˆ= A[i];
rep(j,i,n) if (fabs(b[j]) > eps) return -1; }
break; rank++; This is useful for solving problems on the type
} }
swap(A[i], A[br]); ai = bi ai−1 + ci ai+1 + di , 1 ≤ i ≤ n,
swap(b[i], b[br]); x = bs();
swap(col[i], col[bc]); for (int i = rank; i--;) { where a0 , an+1 , bi , ci and di are known. a can then be obtained from
rep(j,0,n) swap(A[j][i], A[j][bc]); if (!b[i]) continue;
bv = 1/A[i][i]; x[col[i]] = 1; {ai } = tridiagonal({1, −1, −1, ..., −1, 1}, {0, c1 , c2 , . . . , cn },
rep(j,i+1,n) { rep(j,0,i) b[j] ˆ= A[j][i];
{b1 , b2 , . . . , bn , 0}, {a0 , d1 , d2 , . . . , dn , an+1 }).
double fac = A[j][i] * bv; }
b[j] -= fac * b[i]; return rank; // (multiple solutions if rank < m)
} // hash-cpp-all = fa2d7a3e3a84d8fb47610cc474e77b4e Fails if the solution is not unique.
rep(k,i+1,m) A[j][k] -= fac*A[i][k]; If |di | > |pi | + |qi−1 | for all i, or |di | > |pi−1 | + |qi |, or the matrix is
} positive definite, the algorithm is numerically stable and neither tr nor
rank++; the check for diag[i] == 0 is needed.
} MatrixInverse.h
Description: Invert matrix A. Returns rank; result is stored in A un- Time: O (N ) 26 lines
x.assign(m, 0); less singular (rank < n). Can easily be extended to prime moduli; for typedef double T;
for (int i = rank; i--;) { prime powers, repeatedly set A−1 = A−1 (2I − AA−1 ) (mod pk ) where vector<T> tridiagonal(vector<T> diag, const vector<T>&
b[i] /= A[i][i]; A−1 starts as the inverse of A mod p, and k is doubled in each step. ,→super,
MIT NULL fft 5
const vector<T>& sub, vector<T> b) { // hash-cpp-2 = 62f50e0b94ea4486de6fbc07e826040a fft(b, 2*n);
int n = sz(b); vi tr(n); #endif b.resize(n);
rep(i,0,n-1) { }
if (abs(diag[i]) < 1e-9 * abs(super[i])) { // diag[i] using vn = vector<num>; b.resize(a.size());
,→== 0 vi rev({0, 1}); return b;
b[i+1] -= b[i] * diag[i+1] / super[i]; vn rt(2, num(1)), fa, fb; } // hash-cpp-6 = 61660c4b2c75faa72062368a381f059f
if (i+2 < n) b[i+2] -= b[i] * sub[i+1] / super[i];
diag[i+1] = sub[i]; tr[++i] = 1; inline void init(int n) { // hash-cpp-3 #if FFT
} else { if (n <= sz(rt)) return; // Double multiply (num = complex)
diag[i+1] -= super[i]*sub[i]/diag[i]; rev.resize(n); using vd = vector<double>;
b[i+1] -= b[i]*sub[i]/diag[i]; rep(i,0,n) rev[i] = (rev[i>>1] | ((i&1)*n)) >> 1; vd multiply(const vd& a, const vd& b) { // hash-cpp-7
} rt.reserve(n); int s = sz(a) + sz(b) - 1;
} for (int k = sz(rt); k < n; k *= 2) { if (s <= 0) return {};
for (int i = n; i--;) { rt.resize(2*k); int L = s > 1 ? 32 - __builtin_clz(s-1) : 0, n = 1 << L;
if (tr[i]) { #if FFT if (sz(fa) < n) fa.resize(n);
swap(b[i], b[i-1]); double a=M_PI/k; num z(cos(a),sin(a)); // FFT if (sz(fb) < n) fb.resize(n);
diag[i-1] = diag[i]; #else
b[i] /= super[i-1]; num z = pow(num(g), (mod-1)/(2*k)); // NTT fill(fa.begin(), fa.begin() + n, 0);
} else { #endif rep(i,0,sz(a)) fa[i].x = a[i];
b[i] /= diag[i]; rep(i,k/2,k) rt[2*i] = rt[i], rt[2*i+1] = rt[i]*z; rep(i,0,sz(b)) fa[i].y = b[i];
if (i) b[i-1] -= b[i]*super[i-1]; } fft(fa, n);
} } // hash-cpp-3 = 408005a3c0a4559a884205d5d7db44e9 trav(x, fa) x = x * x;
} rep(i,0,n) fb[i] = fa[(n-i)&(n-1)] - conj(fa[i]);
return b; inline void fft(vector<num> &a, int n) { // hash-cpp-4 fft(fb, n);
} // hash-cpp-all = 8f9fa8b1e5e82731da914aed0632312f init(n); vd r(s);
int s = __builtin_ctz(sz(rev)/n); rep(i,0,s) r[i] = fb[i].y / (4*n);
rep(i,0,n) if (i < rev[i]>>s) swap(a[i], a[rev[i]>>s]); return r;
3.1 Fourier transforms for (int k = 1; k < n; k *= 2) } // hash-cpp-7 = c2431bc9cb89b2ad565db6fba6a21a32
fft.cpp for (int i = 0; i < n; i += 2 * k) rep(j,0,k) {
Description: FFT/NTT, polynomial mod/log/exp num t = rt[j+k] * a[i+j+k]; // Integer multiply mod m (num = complex) // hash-cpp-8
303 lines a[i+j+k] = a[i+j] - t; vi multiply_mod(const vi& a, const vi& b, int m) {
namespace fft { a[i+j] = a[i+j] + t; int s = sz(a) + sz(b) - 1;
#if FFT } if (s <= 0) return {};
// FFT } // hash-cpp-4 = 1f0820b04997ddca9b78742df352d419 int L = s > 1 ? 32 - __builtin_clz(s-1) : 0, n = 1 << L;
using dbl = double; if (sz(fa) < n) fa.resize(n);
struct num { // hash-cpp-1 // Complex/NTT if (sz(fb) < n) fb.resize(n);
dbl x, y; vn multiply(vn a, vn b) { // hash-cpp-5
num(dbl x_ = 0, dbl y_ = 0) : x(x_), y(y_) { } int s = sz(a) + sz(b) - 1; rep(i,0,sz(a)) fa[i] = num(a[i] & ((1<<15)-1), a[i] >>
}; if (s <= 0) return {}; ,→15);
inline num operator+(num a, num b) { return num(a.x + b.x, int L = s > 1 ? 32 - __builtin_clz(s-1) : 0, n = 1 << L; fill(fa.begin()+sz(a), fa.begin() + n, 0);
,→a.y + b.y); } a.resize(n), b.resize(n); rep(i,0,sz(b)) fb[i] = num(b[i] & ((1<<15)-1), b[i] >>
inline num operator-(num a, num b) { return num(a.x - b.x, fft(a, n); ,→15);
,→a.y - b.y); } fft(b, n); fill(fb.begin()+sz(b), fb.begin() + n, 0);
inline num operator*(num a, num b) { return num(a.x * b.x - num d = inv(num(n));
,→ a.y * b.y, a.x * b.y + a.y * b.x); } rep(i,0,n) a[i] = a[i] * b[i] * d; fft(fa, n);
inline num conj(num a) { return num(a.x, -a.y); } reverse(a.begin()+1, a.end()); fft(fb, n);
inline num inv(num a) { dbl n = (a.x*a.x+a.y*a.y); return fft(a, n); double r0 = 0.5 / n; // 1/2n
,→num(a.x/n,-a.y/n); } a.resize(s); rep(i,0,n/2+1) {
// hash-cpp-1 = d2cc70ff17fe23dbfe608d8bce4d827b return a; int j = (n-i)&(n-1);
#else } // hash-cpp-5 = 7a20264754593de4eb7963d8fc3d8a15 num g0 = (fb[i] + conj(fb[j])) * r0;
// NTT num g1 = (fb[i] - conj(fb[j])) * r0;
const int mod = 998244353, g = 3; // Complex/NTT power-series inverse swap(g1.x, g1.y); g1.y *= -1;
// For p < 2ˆ30 there is also (5 << 25, 3), (7 << 26, 3), // Doubles b as b[:n] = (2 - a[:n] * b[:n/2]) * b[:n/2] if (j != i) {
// (479 << 21, 3) and (483 << 21, 5). Last two are > 10ˆ9. vn inverse(const vn& a) { // hash-cpp-6 swap(fa[j], fa[i]);
struct num { // hash-cpp-2 if (a.empty()) return {}; fb[j] = fa[j] * g1;
int v; vn b({inv(a[0])}); fa[j] = fa[j] * g0;
num(ll v_ = 0) : v(int(v_ % mod)) { if (v<0) v+=mod; } b.reserve(2*a.size()); }
explicit operator int() const { return v; } while (sz(b) < sz(a)) { fb[i] = fa[i] * conj(g1);
}; int n = 2*sz(b); fa[i] = fa[i] * conj(g0);
inline num operator+(num a,num b){return num(a.v+b.v);} b.resize(2*n, 0); }
inline num operator-(num a,num b){return num(a.v+mod-b.v);} if (sz(fa) < 2*n) fa.resize(2*n); fft(fa, n);
inline num operator*(num a,num b){return num(1ll*a.v*b.v);} fill(fa.begin(), fa.begin()+2*n, 0); fft(fb, n);
inline num pow(num a, int b) { copy(a.begin(), a.begin()+min(n,sz(a)), fa.begin()); vi r(s);
num r = 1; fft(b, 2*n); rep(i,0,s) r[i] = int((ll(fa[i].x+0.5)
do{if(b&1)r=r*a;a=a*a;}while(b>>=1); fft(fa, 2*n); + (ll(fa[i].y+0.5) % m << 15)
return r; num d = inv(num(2*n)); + (ll(fb[i].x+0.5) % m << 15)
} rep(i, 0, 2*n) b[i] = b[i] * (2 - fa[i] * b[i]) * d; + (ll(fb[i].y+0.5) % m << 30)) % m);
inline num inv(num a) { return pow(a, mod-2); } reverse(b.begin()+1, b.end()); return r;
MIT NULL FastSubsetTransform ModularArithmetic ModInverse 6
} // hash-cpp-8 = e8c5f6755ad1e5a976d6c6ffd37b3b22 return b; rep(i,0,n) down[i+n] = poly({y[i]*inv(a[i])});
#endif } // hash-cpp-12 = 94aa209b3e956051e6b3131bf1faafd1 per(i,1,n) down[i] = down[i*2] * up[i*2+1] + down[i*2+1]
poly integ(const poly& a) { // hash-cpp-13 ,→* up[i*2];
} // namespace fft poly b(sz(a)+1); return down[1];
b[1]=1; // mod p } // hash-cpp-18 = 74f15e1e82d51e852b321a1ff75ba1fd
// For multiply_mod, use num = modnum, poly = vector<num> rep(i,2,sz(b)) b[i]=b[fft::mod%i]*(-fft::mod/i); // mod p
using fft::num; rep(i,1,sz(b)) b[i]=a[i-1]*b[i]; // mod p
using poly = fft::vn; //rep(i,1,sz(b)) b[i]=a[i-1]*inv(num(i)); // else FastSubsetTransform.h
using fft::multiply; return b; Description:
X Transform to a basis with fast convolutions of the form
using fft::inverse; } // hash-cpp-13 = 6f13f6a43b2716a116d347000820f0bd c[z] = a[x] · b[y], where ⊕ is one of AND, OR, XOR. The size
z=x⊕y
// hash-cpp-9 poly log(const poly& a) { // a[0] == 1 // hash-cpp-14 of a must be a power of two.
poly& operator+=(poly& a, const poly& b) { poly b = integ(deriv(a)*inverse(a)); Time: O (N log N ) 16 lines
if (sz(a) < sz(b)) a.resize(b.size()); b.resize(a.size());
rep(i,0,sz(b)) a[i]=a[i]+b[i]; return b; void FST(vi& a, bool inv) {
return a; } // hash-cpp-14 = ce1533264298c5382f72a2a1b0947045 for (int n = sz(a), step = 1; step < n; step *= 2) {
} poly exp(const poly& a) { // a[0] == 0 // hash-cpp-15 for (int i = 0; i < n; i += 2 * step) rep(j,i,i+step) {
poly operator+(const poly& a, const poly& b) { poly r=a; r poly b(1,num(1)); int &u = a[j], &v = a[j + step]; tie(u, v) =
,→+=b; return r; } if (a.empty()) return b; inv ? pii(v - u, u) : pii(v, u + v); // AND
poly& operator-=(poly& a, const poly& b) { while (sz(b) < sz(a)) { inv ? pii(v, u - v) : pii(u + v, u); // OR
if (sz(a) < sz(b)) a.resize(b.size()); int n = min(sz(b) * 2, sz(a)); pii(u + v, u - v); // XOR
rep(i,0,sz(b)) a[i]=a[i]-b[i]; b.resize(n); }
return a; poly v = poly(a.begin(), a.begin() + n) - log(b); }
} v[0] = v[0]+num(1); if (inv) trav(x, a) x /= sz(a); // XOR only
poly operator-(const poly& a, const poly& b) { poly r=a; r b *= v; }
,→-=b; return r; } b.resize(n); vi conv(vi a, vi b) {
poly operator*(const poly& a, const poly& b) { } FST(a, 0); FST(b, 0);
// TODO: small-case? return b; rep(i,0,sz(a)) a[i] *= b[i];
return multiply(a, b); } // hash-cpp-15 = f645d091e4ae3ee3dc2aa095d4aa699a FST(a, 1); return a;
} poly pow(const poly& a, int m) { // m >= 0 // hash-cpp-16 } // hash-cpp-all = 3de473e2c1de97e6e9ff0f13542cf3fb
poly& operator*=(poly& a, const poly& b) {return a = a*b;} poly b(a.size());
// hash-cpp-9 = 61b8743c2b07beed0e7ca857081e1bd4 if (!m) { b[0] = 1; return b; }
poly& operator*=(poly& a, const num& b) { // Optional
trav(x, a) x = x * b;
int p = 0;
while (p<sz(a) && a[p].v==0) ++p;
Number theory (4)
return a; if (1ll*m*p >= sz(a)) return b;
} num mu = pow(a[p], m), di = inv(a[p]); 4.1 Modular arithmetic
poly operator*(const poly& a, const num& b) { poly r=a; r*= poly c(sz(a) - m*p);
,→b; return r; } rep(i,0,sz(c)) c[i] = a[i+p] * di;
ModularArithmetic.h
Description: Operators for modular arithmetic. You need to set mod
c = log(c);
to some number first and then you can use the structure.
// Polynomial floor division; no leading 0’s plz trav(v,c) v = v * m;
"euclid.h" 18 lines
poly operator/(poly a, poly b) { // hash-cpp-10 c = exp(c);
if (sz(a) < sz(b)) return {}; rep(i,0,sz(c)) b[i+m*p] = c[i] * mu; const ll mod = 17; // change to something else
int s = sz(a)-sz(b)+1; return b; struct Mod {
reverse(a.begin(), a.end()); } // hash-cpp-16 = 0f4830b9de34c26d39f170069827121f ll x;
reverse(b.begin(), b.end()); Mod(ll xx) : x(xx) {}
a.resize(s); // Multipoint evaluation/interpolation Mod operator+(Mod b) { return Mod((x + b.x) % mod); }
b.resize(s); // hash-cpp-17 Mod operator-(Mod b) { return Mod((x - b.x + mod) % mod);
a = a * inverse(move(b)); vector<num> eval(const poly& a, const vector<num>& x) { ,→ }
a.resize(s); int n=sz(x); Mod operator*(Mod b) { return Mod((x * b.x) % mod); }
reverse(a.begin(), a.end()); if (!n) return {}; Mod operator/(Mod b) { return *this * invert(b); }
return a; vector<poly> up(2*n); Mod invert(Mod a) {
} // hash-cpp-10 = a6589ce8fcf1e33df3b42ee703a7fe60 rep(i,0,n) up[i+n] = poly({0-x[i], 1}); ll x, y, g = euclid(a.x, mod, x, y);
poly& operator/=(poly& a, const poly& b) {return a = a/b;} per(i,1,n) up[i] = up[2*i]*up[2*i+1]; assert(g == 1); return Mod((x + mod) % mod);
poly& operator%=(poly& a, const poly& b) { // hash-cpp-11 vector<poly> down(2*n); }
if (sz(a) >= sz(b)) { down[1] = a % up[1]; Mod operatorˆ(ll e) {
poly c = (a / b) * b; rep(i,2,2*n) down[i] = down[i/2] % up[i]; if (!e) return Mod(1);
a.resize(sz(b)-1); vector<num> y(n); Mod r = *this ˆ (e / 2); r = r * r;
rep(i,0,sz(a)) a[i] = a[i]-c[i]; rep(i,0,n) y[i] = down[i+n][0]; return e&1 ? *this * r : r;
} return y; }
return a; } // hash-cpp-17 = a079eba46c3110851ec6b0490b439931 }; // hash-cpp-all = 35bfea8c111cb24c4ce84c658446961b
} // hash-cpp-11 = 9af255f48abbeafd8acde353357b84fd // hash-cpp-18
poly operator%(const poly& a, const poly& b) { poly r=a; r poly interp(const vector<num>& x, const vector<num>& y) { ModInverse.h
,→%=b; return r; } int n=sz(x); Description: Pre-computation of modular inverses. Assumes LIM ≤
assert(n); mod and that mod is a prime.
// Log/exp/pow vector<poly> up(n*2); 4 lines
poly deriv(const poly& a) { // hash-cpp-12 rep(i,0,n) up[i+n] = poly({0-x[i], 1}); const ll mod = 1000000007, LIM = 200000;
if (a.empty()) return {}; per(i,1,n) up[i] = up[2*i]*up[2*i+1]; ll* inv = new ll[LIM] - 1; inv[1] = 1;
poly b(sz(a)-1); vector<num> a = eval(deriv(up[1]), x); rep(i,2,LIM) inv[i] = mod - (mod / i) * inv[mod % i] % mod;
rep(i,1,sz(a)) b[i-1]=a[i]*i; vector<poly> down(2*n); // hash-cpp-all = 6f684f0b9ae6c69f42de68f023a81de5
MIT NULL ModPow ModSum ModMulLL ModSqrt eratosthenes MillerRabin factor euclid Euclid 7
ModPow.h 6 lines
assert(modpow(a, (p-1)/2, p) == 1); }
if (p % 4 == 3) return modpow(a, (p+1)/4, p); return true;
const ll mod = 1000000007; // faster if const // aˆ(n+3)/8 or 2ˆ(n+3)/8 * 2ˆ(n-1)/4 works if p % 8 == 5 } // hash-cpp-all = ccddf18bab60a654ff4af45e95dd60b6
ll modpow(ll a, ll e) { ll s = p - 1;
if (e == 0) return 1; int r = 0;
ll x = modpow(a * a % mod, e >> 1); while (s % 2 == 0) factor.h
return e & 1 ? x * a % mod : x; ++r, s /= 2; Description: Pollard’s rho algorithm. It is a probabilistic factorisation
} // hash-cpp-all = 2fa6d9ccac4586cba0618aad18cdc9de ll n = 2; // find a non-square mod p algorithm, whose expected time complexity is good. Before you start
while (modpow(n, (p - 1) / 2, p) != p - 1) ++n; using it, run init(bits), where bits is the length of the numbers you
use. Returns factors of the input without duplicates.
ModSum.h ll x = modpow(a, (s + 1) / 2, p);
Time: Expected running time should be good enough for 50-bit num-
Description: Sums of mod’ed arithmetic progressions. ll b = modpow(a, s, p);
Pto−1 ll g = modpow(n, s, p); bers.
modsum(to, c, k, m) = i=0 (ki + c)%m. divsum is similar but for "ModMulLL.h", "MillerRabin.h", "eratosthenes.h" 35 lines
floored division. for (;;) {
Time: log(m), with a large constant. ll t = b; vector<ull> pr;
19 lines ull f(ull a, ull n, ull &has) {
int m = 0;
typedef unsigned long long ull; for (; m < r; ++m) { return (mod_mul(a, a, n) + has) % n;
ull sumsq(ull to) { return to / 2 * ((to-1) | 1); } if (t == 1) break; }
t = t * t % p; vector<ull> factor(ull d) {
ull divsum(ull to, ull c, ull k, ull m) { } vector<ull> res;
ull res = k / m * sumsq(to) + c / m * to; if (m == 0) return x; for (int i = 0; i < sz(pr) && pr[i]*pr[i] <= d; i++)
k %= m; c %= m; ll gs = modpow(g, 1 << (r - m - 1), p); if (d % pr[i] == 0) {
if (k) { g = gs * gs % p; while (d % pr[i] == 0) d /= pr[i];
ull to2 = (to * k + c) / m; x = x * gs % p; res.push_back(pr[i]);
res += to * to2; b = b * g % p; }
res -= divsum(to2, m-1 - c, m, k) + to2; r = m; //d is now a product of at most 2 primes.
} } if (d > 1) {
return res; } // hash-cpp-all = 83e24bd39c8c93946ad3021b8ca6c3c4 if (prime(d))
} res.push_back(d);
else while (true) {
ll modsum(ull to, ll c, ll k, ll m) { 4.2 Primality ull has = rand() % 2321 + 47;
c = ((c % m) + m) % m; ull x = 2, y = 2, c = 1;
k = ((k % m) + m) % m;
eratosthenes.h for (; c==1; c = __gcd((y > x ? y - x : x - y), d)) {
Description: Prime sieve for generating all primes up to a certain limit.
return to * c + k * sumsq(to) - m * divsum(to, c, k, m); x = f(x, d, has);
isprime[i] is true iff i is a prime.
} // hash-cpp-all = 8d6e082e0ea6be867eaea12670d08dcc y = f(f(y, d, has), d, has);
Time: lim=100’000’000 ≈ 0.8 s. Runs 30% faster if only odd indices
}
are stored. 11 lines if (c != d) {
ModMulLL.h const int MAX_PR = 5000000; res.push_back(c); d /= c;
Description: Calculate a · b mod c (or ab mod c) for large c. if (d != c) res.push_back(d);
bitset<MAX_PR> isprime;
Time: O (64/bits · log b), where bits = 64 − k, if we want to deal with break;
vi eratosthenes_sieve(int lim) {
k-bit numbers. 19 lines }
isprime.set(); isprime[0] = isprime[1] = 0;
typedef unsigned long long ull; for (int i = 4; i < lim; i += 2) isprime[i] = 0; }
const int bits = 10; for (int i = 3; i*i < lim; i += 2) if (isprime[i]) }
// if all numbers are less than 2ˆk, set bits = 64-k for (int j = i*i; j < lim; j += i*2) isprime[j] = 0; return res;
const ull po = 1 << bits; vi pr; }
ull mod_mul(ull a, ull b, ull &c) { rep(i,2,lim) if (isprime[i]) pr.push_back(i); void init(int bits) {//how many bits do we use?
ull x = a * (b & (po - 1)) % c; return pr; vi p = eratosthenes_sieve(1 << ((bits + 2) / 3));
while ((b >>= bits) > 0) { } // hash-cpp-all = 0564a3337fb69c0b87dfd3c56cdfe2e3 pr.assign(all(p));
a = (a << bits) % c; } // hash-cpp-all = 67b304bd690b2a8445a7b4dbf93996d7
x += (a * (b & (po - 1))) % c;
MillerRabin.h
}
return x % c; Description: Miller-Rabin primality probabilistic test. Probability of 4.3 Divisibility
} failing one iteration is at most 1/4. 15 iterations should be enough for euclid.h
ull mod_pow(ull a, ull b, ull mod) { 50-bit numbers. Description: Finds the Greatest Common Divisor to the integers a and
if (b == 0) return 1; Time: 15 times the complexity of ab mod c. b. Euclid also finds two integers x and y, such that ax + by = gcd(a, b).
"ModMulLL.h" 16 lines
ull res = mod_pow(a, b / 2, mod); If a and b are coprime, then x is the inverse of a (mod b). 7 lines
res = mod_mul(res, res, mod); bool prime(ull p) {
if (b & 1) return mod_mul(res, a, mod); if (p == 2) return true; ll gcd(ll a, ll b) { return __gcd(a, b); }
return res; if (p == 1 || p % 2 == 0) return false;
} // hash-cpp-all = 40cd743544228d297c803154525107ab ull s = p - 1; ll euclid(ll a, ll b, ll &x, ll &y) {
while (s % 2 == 0) s /= 2; if (b) { ll d = euclid(b, a % b, y, x);
rep(i,0,15) { return y -= a/b * x, d; }
ModSqrt.h ull a = rand() % (p - 1) + 1, tmp = s; return x = 1, y = 0, a;
Description: Tonelli-Shanks algorithm for modular square roots. ull mod = mod_pow(a, tmp, p); } // hash-cpp-all = 63e6f8d2f560b27cb800273d63d2102c
Time: O log2 p worst case, often O (log p)

while (tmp != p - 1 && mod != 1 && mod != p - 1) {
"ModPow.h" 30 lines mod = mod_mul(mod, mod, p);
ll sqrt(ll a, ll p) { tmp *= 2;
Euclid.java
Description: Finds {x, y, d} s.t. ax + by = d = gcd(a, b). 11 lines
a %= p; if (a < 0) a += p; }
if (a == 0) return 0; if (mod != p - 1 && tmp % 2 == 0) return false; static BigInteger[] euclid(BigInteger a, BigInteger b) {
MIT NULL ContinuedFractions FracBinarySearch chinese IntPerm 8
BigInteger x = BigInteger.ONE, yy = x; for (int si = 0; step; (step *= 2) >>= si) { 4.8 Estimates
BigInteger y = BigInteger.ZERO, xx = y; adv += step; P
while (b.signum() != 0) { Frac mid{lo.p * adv + hi.p, lo.q * adv + hi.q}; d|n d = O(n log log n).
BigInteger q = a.divide(b), t = b; if (abs(mid.p) > N || mid.q > N || dir == !f(mid)) {
b = a.mod(b); a = t; adv -= step; si = 2; The number of divisors of n is at most around 100 for
t = xx; xx = x.subtract(q.multiply(xx)); x = t; }
t = yy; yy = y.subtract(q.multiply(yy)); y = t; }
n < 5e4, 500 for n < 1e7, 2000 for n < 1e10, 200 000 for
} hi.p += lo.p * adv; n < 1e19.
return new BigInteger[]{x, y, a}; hi.q += lo.q * adv;
} dir = !dir;
swap(lo, hi); Combinatorial (5)
4.4 Fractions A = B; B = !!adv;

ContinuedFractions.h
}
return dir ? hi : lo;
5.1 Permutations
Description: Given N and a real number x ≥ 0, finds the closest ra- } // hash-cpp-all = 214844f17d0c347ff436141729e0c829 5.1.1 Factorial
tional approximation p/q with p, q ≤ N . It will obey |p/q − x| ≤ 1/qN .
For consecutive convergents, pk+1 qk − qk+1 pk = (−1)k . (pk /qk alter- 4.5 Chinese remainder theorem
nates between > x and < x.) If x is rational, y eventually becomes ∞; if n 123 4 5 6 7 8 9 10
x is the root of a degree 2 polynomial the a’s eventually become cyclic. chinese.h
Time: O (log N ) 21 lines Description: Chinese Remainder Theorem. n! 1 2 6 24 120 720 5040 40320 362880 3628800
chinese(a, m, b, n) returns a number x, such that x ≡ a (mod m) n 11 12 13 14 15 16 17
typedef double d; // for N ∼ 1e7; long double for N ∼ 1e9
and x ≡ b (mod n). For not coprime n, m, use chinese common. Note
pair<ll, ll> approximate(d x, ll N) { n! 4.0e7 4.8e8 6.2e9 8.7e10 1.3e12 2.1e13 3.6e14
that all numbers must be less than 231 if you have Z = unsigned long
ll LP = 0, LQ = 1, P = 1, Q = 0, inf = LLONG_MAX; d y = x
long. n 20 25 30 40 50 100 150 171
,→;
Time: log(m + n)
for (;;) { n! 2e18 2e25 3e32 8e47 3e64 9e157 6e262 >DBL MAX
"euclid.h" 13 lines
ll lim = min(P ? (N-LP) / P : inf, Q ? (N-LQ) / Q : inf
,→), template<class Z> Z chinese(Z a, Z m, Z b, Z n) {
a = (ll)floor(y), b = min(a, lim), Z x, y; euclid(m, n, x, y); IntPerm.h
NP = b*P + LP, NQ = b*Q + LQ; Z ret = a * (y + m) % m * n + b * (x + n) % n * m; Description: Permutation -> integer conversion. (Not order preserv-
if (a > b) { if (ret >= m * n) ret -= m * n; ing.)
// If b > a/2, we have a semi-convergent that gives return ret; Time: O (n) 6 lines
,→us a }
int permToInt(vi& v) {
// better approximation; if b = a/2, we *may* have int use = 0, i = 0, r = 0;
,→one. template<class Z> Z chinese_common(Z a, Z m, Z b, Z n) {
trav(x,v)r=r * ++i + __builtin_popcount(use & -(1 << x)),
// Return {P, Q} here for a more canonical Z d = gcd(m, n);
use |= 1 << x; // (note: minus, not ∼!)
,→approximation. if (((b -= a) %= n) < 0) b += n;
return r;
return (abs(x - (d)NP / (d)NQ) < abs(x - (d)P / (d)Q) if (b % d) return -1; // No solution
} // hash-cpp-all = e1b8eaea02324af14a3da94f409019b8
,→) ? return d * chinese(Z(0), m/d, b/d, n/d) + a;
make_pair(NP, NQ) : make_pair(P, Q); } // hash-cpp-all = da3099704e14964aa045c152bb478c14
} 5.1.2 Cycles
if (abs(y = 1/(y - (d)a)) > 3*N) {
return {NP, NQ};
4.6 Pythagorean Triples Let gS (n) be the number of n-permutations whose cycle
} The Pythagorean triples are uniquely generated lengths all belong to the set S. Then
LP = P; P = NP; ∞
!
LQ = Q; Q = NQ;
by X xn X xn
}
gS (n) = exp
n! n
} // hash-cpp-all = dd6c5e1084a26365dc6321bd935975d9 a = k · (m2 − n2 ), b = k · (2mn), c = k · (m2 + n2 ), n=0 n∈S

FracBinarySearch.h 5.1.3 Derangements


Description: Given f and N , finds the smallest fraction p/q ∈ [0, 1] with m > n > 0, k > 0, m⊥n, and either m or n
Permutations of a set such that none of the elements
such that f (p/q) is true, and p, q ≤ N . You may want to throw an even. appear in their original position.
exception from f if it finds an exact solution, in which case N can be
removed.
fracBS([](Frac f) { return f.p>=3*f.q; }, 10); //
4.7 Primes 
n!

Usage: D(n) = (n−1)(D(n−1)+D(n−2)) = nD(n−1)+(−1)n =
{1,3} p = 962592769 is such that 221 | p − 1, which may be e
Time: O (log(N )) 24 lines
useful. For hashing use 970592641 (31-bit number),
struct Frac { ll p, q; };
31443539979727 (45-bit), 3006703054056749 (52-bit). 5.1.4 Burnside’s lemma
template<class F> There are 78498 primes less than 1 000 000. Given a group G of symmetries and a set X, the number
Frac fracBS(F f, ll N) { of elements of X up to symmetry equals
bool dir = 1, A = 1, B = 1;
Frac lo{0, 1}, hi{1, 1}; // Set hi to 1/0 to search (0, N
Primitive roots exist modulo any prime power pa , except 1 X g
,→] for p = 2, a > 2, and there are φ(φ(pa )) many. For |X |,
|G| g∈G
assert(!f(lo)); assert(f(hi)); ×
while (A || B) {
p = 2, a > 2, the group Z2a is instead isomorphic to
ll adv = 0, step = 1; // move hi if dir, else lo Z2 × Z2a−2 . where X g are the elements fixed by g (g.x = x).
MIT NULL binomialModPrime multinomial nim-product 9
If f (n) counts ”configurations” (of some sort) of length Sums of powers: 5.3.5 Bell numbers
n, we can ignore rotational symmetry using G = Zn to ! Total number of partitions of n distinct elements.
n m
get X 1 X m+1 B(n) = 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, . . . . For p
nm = Bk (n + 1)m+1−k
i=1
m+1 k prime,
k=0
n−1
1X 1X
g(n) = f (gcd(n, k)) = f (k)φ(n/k).
n
k=0
n
k|n Euler-Maclaurin formula for infinite sums: B(pm + n) ≡ mB(n) + B(n + 1) (mod p)
∞ Z ∞ ∞
X X Bk (k−1) 5.3.6 Labeled unrooted trees
f (i) = f (x)dx − f (m)
5.2 Partitions and subsets i=m m k!
k=1 # on n vertices: nn−2
5.2.1 Partition function ∞ 0
# on k existing trees of size ni : n1 n2 · · · nk nk−2
f 000 (m)
Z
Number of ways of writing n as a sum of positive f (m) f (m)
≈ f (x)dx + − + + O(f (5) (m)) # with degrees di : (n − 2)!/((d1 − 1)! · · · (dn − 1)!)
integers, disregarding the order of the summands. m 2 12 720
5.3.7 Catalan numbers
X 5.3.2 Stirling numbers of the first kind
p(0) = 1, p(n) = (−1)k+1 p(n − k(3k − 1)/2) Number of permutations on n items with k cycles.      
k∈Z\{0} 1 2n 2n 2n (2n)!
Cn = = − =
√ c(n, k) = c(n − 1, k − 1) + (n − 1)c(n − 1, k), c(0, 0) = 1 n+1 n n n+1 (n + 1)!n!
p(n) ∼ 0.145/n · exp(2.56 n) Pn k
k=0 c(n, k)x = x(x + 1) . . . (x + n − 1)
2(2n + 1) X
n 0 1 2 3 4 5 6 7 8 9 20 50 100 C0 = 1, Cn+1 = Cn , Cn+1 = Ci Cn−i
c(8, k) = n+2
p(n) 1 1 2 3 5 7 11 15 22 30 627 ∼2e5 ∼2e8
5.2.2 Binomials 8, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1 Cn = 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, . . .
binomialModPrime.h c(n, 2) =
Description: Lucas’ thm: Let n, m be non-negative integers and p a 0, 0, 1, 3, 11, 50, 274, 1764, 13068, 109584, . . . • sub-diagonal monotone paths in an n × n grid.
prime. Write = nk pk +... + n1 p + n0 and m = mk pk + ... + m1 p + m0 .
nQ • strings with n pairs of parenthesis, correctly
n k ni
Then m ≡ i=0 mi (mod p). fact and invfact must hold pre- 5.3.3 Eulerian numbers nested.
computed factorials / inverse factorials, e.g. from ModInverse.h. Number of permutations π ∈ Sn in which exactly k
Time: O logp n

10 lines
• binary trees with with n + 1 leaves (0 or 2
elements are greater than the previous element. k j:s s.t. children).
ll chooseModP(ll n, ll m, int p, vi& fact, vi& invfact) {
ll c = 1; π(j) > π(j + 1), k + 1 j:s s.t. π(j) ≥ j, k j:s s.t. • ordered trees with n + 1 vertices.
while (n || m) { π(j) > j. • ways a convex polygon with n + 2 sides can be cut
ll a = n % p, b = m % p;
if (a < b) return 0; into triangles by connecting vertices with straight
c = c * fact[a] % p * invfact[b] % p * invfact[a - b] % E(n, k) = (n − k)E(n − 1, k − 1) + (k + 1)E(n − 1, k) lines.
,→ p;
n /= p; m /= p; • permutations of [n] with no 3-term increasing
} E(n, 0) = E(n, n − 1) = 1
return c; subseq.
} // hash-cpp-all = 81845faa6ecd635c391e4f0134f0676c k  
X
j n+1 5.4 Other
E(n, k) = (−1) (k + 1 − j)n
multinomial.h P j=0
j nim-product.cpp
k + · · · + k  ( ki )! Description: Nim Product.
1 n 17 lines
Description: Computes = .
k1 , k2 , . . . , kn k1 !k2 !...kn ! 6 lines using ull = uint64_t;
ll multinomial(vi& v) {
5.3.4 Stirling numbers of the second kind ull _nimProd2[64][64];
ll c = 1, m = v.empty() ? 1 : v[0]; Partitions of n distinct elements into exactly k ull nimProd2(int i, int j) {
rep(i,1,sz(v)) rep(j,0,v[i]) if (_nimProd2[i][j]) return _nimProd2[i][j];
c = c * ++m / (j+1);
groups. if ((i & j) == 0) return _nimProd2[i][j] = 1ull << (i|j);
return c; int a = (i&j) & -(i&j);
} // hash-cpp-all = a0a3128f6afa4721166feb182b82f130 S(n, k) = S(n − 1, k − 1) + kS(n − 1, k) return _nimProd2[i][j] = nimProd2(i ˆ a, j) ˆ nimProd2((i
,→ ˆ a) | (a-1), (j ˆ a) | (i & (a-1)));
}
5.3 General purpose numbers S(n, 1) = S(n, n) = 1 ull nimProd(ull x, ull y) {
ull res = 0;
5.3.1 Bernoulli numbers k   for (int i = 0; x >> i; i++)
EGF of Bernoulli numbers is B(t) = t
(FFT-able). 1 X k n if ((x >> i) & 1)
et −1 S(n, k) = (−1)k−j j for (int j = 0; y >> j; j++)
B[0, . . .] = [1, − 12 , 16 , 0, − 30
1 1
, 0, 42 , . . .] k! j=0 j if ((y >> j) & 1)
MIT NULL schreier-sims EulerWalk PushRelabel MinCostMaxFlow 10
res ˆ= nimProd2(i, j); 6.1 Euler walk Edge &back = g[e.dest][e.back];
return res; if (!ec[e.dest] && f) hs[H[e.dest]].push_back(e.dest);
} // hash-cpp-all = e0411498c7a77d77ae793efab5500851 EulerWalk.h e.f += f; e.c -= f; ec[e.dest] += f;
Description: Eulerian undirected/directed path/cycle algorithm. Re- back.f -= f; back.c += f; ec[back.dest] -= f;
turns a list of nodes in the Eulerian path/cycle with src at both start }
schreier-sims.cpp and end, or empty list if no cycle/path exists. To get edge indices back, Flow maxflow(int s, int t) {
Description: Check group membership of permutation groups also put it->second in s (and then ret). int v = sz(g); H[s] = v; ec[t] = 1;
52 lines
Time: O (E) where E is the number of edges. 27 lines vi co(2*v); co[0] = v-1;
struct Perm {
struct V { rep(i,0,v) cur[i] = g[i].data();
int a[N];
vector<pii> outs; // (dest, edge index) trav(e, g[s]) add_flow(e, e.c);
Perm() {
for (int i = 1; i <= n; ++i) a[i] = i; int nins = 0;
}; for (int hi = 0;;) {
}
while (hs[hi].empty()) if (!hi--) return -ec[s];
friend Perm operator* (const Perm &lhs, const Perm &rhs)
vi euler_walk(vector<V>& nodes, int nedges, int src=0) { int u = hs[hi].back(); hs[hi].pop_back();
,→{
int c = 0; while (ec[u] > 0) // discharge u
static Perm res;
trav(n, nodes) c += abs(n.nins - sz(n.outs)); if (cur[u] == g[u].data() + sz(g[u])) {
for (int i = 1; i <= n; ++i) res.a[i] = lhs.a[rhs.a[i
if (c > 2) return {}; H[u] = 1e9;
,→]];
vector<vector<pii>::iterator> its; trav(e, g[u]) if (e.c && H[u] > H[e.dest]+1)
return res;
trav(n, nodes) H[u] = H[e.dest]+1, cur[u] = &e;
}
its.push_back(n.outs.begin()); if (++co[H[u]], !--co[hi] && hi < v)
friend Perm inv(const Perm &cur) {
vector<bool> eu(nedges); rep(i,0,v) if (hi < H[i] && H[i] < v)
static Perm res;
vi ret, s = {src}; --co[H[i]], H[i] = v + 1;
for (int i = 1; i <= n; ++i) res.a[cur.a[i]] = i;
while(!s.empty()) { hi = H[u];
return res;
int x = s.back(); } else if (cur[u]->c && H[u] == H[cur[u]->dest]+1)
}
auto& it = its[x], end = nodes[x].outs.end(); add_flow(*cur[u], min(ec[u], cur[u]->c));
};
while(it != end && eu[it->second]) ++it; else ++cur[u];
class Group {
if(it == end) { ret.push_back(x); s.pop_back(); } }
bool flag[N];
else { s.push_back(it->first); eu[it->second] = true; } }
Perm w[N];
} }; // hash-cpp-all = aaa2dd3fd7d9e6d994b295a959664c9a
std::vector<Perm> x;
public: if(sz(ret) != nedges+1)
void clear(int p) { ret.clear(); // No Eulerian cycles/paths.
memset(flag, 0, sizeof flag); // else, non-cycle if ret.front() != ret.back() MinCostMaxFlow.h
for (int i = 1; i <= n; ++i) w[i] = Perm(); reverse(all(ret)); Description: Min-cost max-flow. cap[i][j] != cap[j][i] is allowed; double
flag[p] = true; return ret; edges are not. If costs can be negative, call setpi before maxflow, but
x.clear(); } // hash-cpp-all = f8bd47ef7a9ffb45f7541c41e476f5f9 note that negative cost cycles are not supported. To obtain the actual
} flow, look at positive values only.
Time: Approximately O E 2

friend bool check(const Perm&, int);
friend void insert(const Perm&, int); 6.2 Network flow 81 lines

friend void updateX(const Perm&, int); #include <bits/extc++.h>


} g[N];
PushRelabel.h
Description: Push-relabel using the highest label selection rule and const ll INF = numeric_limits<ll>::max() / 4;
bool check(const Perm &cur, int k) {
the gap heuristic. Quite fast in practice. To obtain the actual flow, look typedef vector<ll> VL;
if (!k) return true;
at positivevalues 
only.
int t = cur.a[k]; √
return g[k].flag[t] ? check(g[k].w[t] * cur, k - 1) : Time: O V 2 E struct MCMF {
51 lines int N;
,→false;
} typedef ll Flow; vector<vi> ed, red;
void updateX(const Perm&, int); struct Edge { vector<VL> cap, flow, cost;
void insert(const Perm &cur, int k) { int dest, back; vi seen;
if (check(cur, k)) return; Flow f, c; VL dist, pi;
g[k].x.push_back(cur); }; vector<pii> par;
for (int i = 1; i <= n; ++i) if (g[k].flag[i]) updateX(
,→cur * inv(g[k].w[i]), k); struct PushRelabel { MCMF(int N) :
} vector<vector<Edge>> g; N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap
void updateX(const Perm &cur, int k) { vector<Flow> ec; ,→),
int t = cur.a[k]; vector<Edge*> cur; seen(N), dist(N), pi(N), par(N) {}
if (g[k].flag[t]) { vector<vi> hs; vi H;
insert(g[k].w[t] * cur, k - 1); PushRelabel(int n) : g(n), ec(n), cur(n), hs(2*n), H(n) void addEdge(int from, int to, ll cap, ll cost) {
} else { ,→{} this->cap[from][to] = cap;
g[k].w[t] = inv(cur); this->cost[from][to] = cost;
g[k].flag[t] = true; void add_edge(int s, int t, Flow cap, Flow rcap=0) { ed[from].push_back(to);
for (int i = 0; i < g[k].x.size(); ++i) updateX(g[k].x[ if (s == t) return; red[to].push_back(from);
,→i] * cur, k); Edge a = {t, sz(g[t]), 0, cap}; }
} Edge b = {s, sz(g[s]), 0, rcap};
} // hash-cpp-all = 949a6e50dbdaea9cda09928c7eabedbc g[s].push_back(a); void path(int s) {
g[t].push_back(b); fill(all(seen), 0);
} fill(all(dist), INF);
dist[s] = 0; ll di;
Graph (6) void add_flow(Edge& e, Flow f) {
MIT NULL EdmondsKarp MinCut GlobalMinCut hopcroftKarp DFSMatching 11
__gnu_pbds::priority_queue<pair<ll, int>> q; rep(j,0,N)
vector<decltype(q)::point_iterator> its(N); for (;;) { w[j] += weights[k][j];
q.push({0, s}); fill(all(par), -1); added[k] = true;
par[source] = 0; }
auto relax = [&](int i, ll cap, ll cost, int dir) { int ptr = 1; }
ll val = di - pi[i] + cost; q[0] = source; }
if (cap && val < dist[i]) { return {best_weight, best_cut};
dist[i] = val; rep(i,0,ptr) { } // hash-cpp-all = 03261f13665169d285596975383c72b3
par[i] = {s, dir}; int x = q[i];
if (its[i] == q.end()) its[i] = q.push({-dist[i], i trav(e, graph[x]) {
,→}); if (par[e.first] == -1 && e.second > 0) {
else q.modify(its[i], {-dist[i], i}); par[e.first] = x; 6.3 Matching
} q[ptr++] = e.first;
}; if (e.first == sink) goto out; hopcroftKarp.h
} Description: Find a maximum matching in a bipartite graph.
while (!q.empty()) { } Usage: vi
√ba(m, -1); hopcroftKarp(g, ba);
s = q.top().second; q.pop(); } Time: O VE
seen[s] = 1; di = dist[s] + pi[s]; return flow; 45 lines

trav(i, ed[s]) if (!seen[i]) out: bool dfs(int a, int layer, const vector<vi>& g, vi& btoa,
relax(i, cap[s][i] - flow[s][i], cost[s][i], 1); T inc = numeric_limits<T>::max(); vi& A, vi& B) {
trav(i, red[s]) if (!seen[i]) for (int y = sink; y != source; y = par[y]) if (A[a] != layer) return 0;
relax(i, flow[i][s], -cost[i][s], 0); inc = min(inc, graph[par[y]][y]); A[a] = -1;
} trav(b, g[a]) if (B[b] == layer + 1) {
rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF); flow += inc; B[b] = -1;
} for (int y = sink; y != source; y = par[y]) { if (btoa[b] == -1 || dfs(btoa[b], layer+2, g, btoa, A,
int p = par[y]; ,→B))
pair<ll, ll> maxflow(int s, int t) { if ((graph[p][y] -= inc) <= 0) graph[p].erase(y); return btoa[b] = a, 1;
ll totflow = 0, totcost = 0; graph[y][p] += inc; }
while (path(s), seen[t]) { } return 0;
ll fl = INF; } }
for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) } // hash-cpp-all = 979bb9ccc85090e328209bf565a2af26
fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p int hopcroftKarp(const vector<vi>& g, vi& btoa) {
,→]); int res = 0;
totflow += fl; MinCut.h vi A(g.size()), B(btoa.size()), cur, next;
for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p) Description: After running max-flow, the left side of a min-cut from s for (;;) {
if (r) flow[p][x] += fl; to t is given by all vertices reachable from s, only traversing edges with fill(all(A), 0);
else flow[x][p] -= fl; positive residual capacity. 1 lines fill(all(B), -1);
} cur.clear();
// hash-cpp-all = d41d8cd98f00b204e9800998ecf8427e
rep(i,0,N) rep(j,0,N) totcost += cost[i][j] * flow[i][j trav(a, btoa) if(a != -1) A[a] = -1;
,→]; rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a);
return {totflow, totcost}; GlobalMinCut.h for (int lay = 1;; lay += 2) {
} Description: Find a global minimum cut in an undirected graph, as bool islast = 0;
represented by an adjacency matrix. next.clear();
// If some costs can be negative, call this before Time: O V 3 trav(a, cur) trav(b, g[a]) {
,→maxflow: 31 lines if (btoa[b] == -1) {
void setpi(int s) { // (otherwise, leave this out) pair<int, vi> GetMinCut(vector<vi>& weights) { B[b] = lay;
fill(all(pi), INF); pi[s] = 0; int N = sz(weights); islast = 1;
int it = N, ch = 1; ll v; vi used(N), cut, best_cut; }
while (ch-- && it--) int best_weight = -1; else if (btoa[b] != a && B[b] == -1) {
rep(i,0,N) if (pi[i] != INF) B[b] = lay;
trav(to, ed[i]) if (cap[i][to]) for (int phase = N-1; phase >= 0; phase--) { next.push_back(btoa[b]);
if ((v = pi[i] + cost[i][to]) < pi[to]) vi w = weights[0], added = used; }
pi[to] = v, ch = 1; int prev, k = 0; }
assert(it >= 0); // negative cost cycle rep(i,0,phase){ if (islast) break;
} prev = k; if (next.empty()) return res;
}; // hash-cpp-all = 6915cee27314b77b2f5e256f1a96cdc0 k = -1; trav(a, next) A[a] = lay+1;
rep(j,1,N) cur.swap(next);
if (!added[j] && (k == -1 || w[j] > w[k])) k = j; }
EdmondsKarp.h if (i == phase-1) { rep(a,0,sz(g)) {
Description: Flow algorithm with guaranteed complexity O(V E 2 ). To rep(j,0,N) weights[prev][j] += weights[k][j]; if(dfs(a, 0, g, btoa, A, B))
get edge flow values, compare capacities before and after, and take the rep(j,0,N) weights[j][prev] = weights[prev][j]; ++res;
positive values only. used[k] = true; }
35 lines cut.push_back(k); }
template<class T> T edmondsKarp(vector<unordered_map<int, T if (best_weight == -1 || w[k] < best_weight) { } // hash-cpp-all = ee9fe891045fe156e995ef0276b80af6
,→>>& graph, int source, int sink) { best_cut = cut;
assert(source != sink); best_weight = w[k];
T flow = 0; } DFSMatching.h
vi par(sz(graph)), q = par; } else {
MIT NULL WeightedMatching GeneralMatching blossom 12
Description: This is a simple matching algorithm but should be just while (L[s] != -1) s++; int r = rand() % mod;
fine in most cases. Graph g should be a list of neighbours of the left fill(all(dad), -1); mat[i][j] = r, mat[j][i] = (mod - r) % mod;
partition. n is the size of the left partition and m is the size of the fill(all(seen), 0); }
right partition. If you want to get the matched pairs, match[i] contains rep(k,0,n) }
match for vertex i on the right side or −1 if it’s not matched. dist[k] = cost[s][k] - u[s] - v[k]; } while (matInv(A = mat) != M);
Time: O (EV ) where E is the number of edges and V is the number of
vertices. 24 lines
int j = 0; vi has(M, 1); vector<pii> ret;
for (;;) { rep(it,0,M/2) {
vi match; j = -1; rep(i,0,M) if (has[i])
vector<bool> seen; rep(k,0,n){ rep(j,i+1,M) if (A[i][j] && mat[i][j]) {
bool find(int j, const vector<vi>& g) { if (seen[k]) continue; fi = i; fj = j; goto done;
if (match[j] == -1) return 1; if (j == -1 || dist[k] < dist[j]) j = k; } assert(0); done:
seen[j] = 1; int di = match[j]; } if (fj < N) ret.emplace_back(fi, fj);
trav(e, g[di]) seen[j] = 1; has[fi] = has[fj] = 0;
if (!seen[e] && find(e, g)) { int i = R[j]; rep(sw,0,2) {
match[e] = di; if (i == -1) break; ll a = modpow(A[fi][fj], mod-2);
return 1; rep(k,0,n) { rep(i,0,M) if (has[i] && A[i][fj]) {
} if (seen[k]) continue; ll b = A[i][fj] * a % mod;
return 0; auto new_dist = dist[j] + cost[i][k] - u[i] - v[k]; rep(j,0,M) A[i][j] = (A[i][j] - A[fi][j] * b) % mod
} if (dist[k] > new_dist) { ,→;
int dfs_matching(const vector<vi>& g, int n, int m) { dist[k] = new_dist; }
match.assign(m, -1); dad[k] = j; swap(fi,fj);
rep(i,0,n) { } }
seen.assign(m, 0); } }
trav(j,g[i]) } return ret;
if (find(j, g)) { } // hash-cpp-all = bb8be4f4f83b4e4ccafaebf8534e4f82
match[j] = i; rep(k,0,n) {
break; if (k == j || !seen[k]) continue;
} auto w = dist[k] - dist[j];
} v[k] += w, u[R[k]] -= w;
blossom.h
return m - (int)count(all(match), -1); Description: O(EV) general matching 65 lines
}
} // hash-cpp-all = 178c94b6091dc009a15d348aef80dff0 u[s] += dist[j]; // vertices 1∼n, chd[x]=0 or y (x match y)
int n;
WeightedMatching.h while (dad[j] >= 0) { vector<int> g[N];
Description: Min cost bipartite matching. Negate costs for max cost. int d = dad[j]; int chd[N],nex[N],fl[N],fa[N];
Time: O N 3 R[j] = R[d]; int gf(int x){return fa[x]==x?x:fa[x]=gf(fa[x]);}
75 lines L[R[j]] = j; void un(int x,int y){x=gf(x),y=gf(y);fa[x]=y;}
typedef vector<double> vd; j = d; int qu[N],p,q;
bool zero(double x) { return fabs(x) < 1e-10; } } int lca(int u,int v){
double MinCostMatching(const vector<vd>& cost, vi& L, vi& R R[j] = s; static int t=0,x[N];
,→) { L[s] = j; t++;
int n = sz(cost), mated = 0; } for(;; swap(u,v) )
vd dist(n), u(n), v(n); auto value = vd(1)[0]; if(u){
vi dad(n), seen(n); rep(i,0,n) value += cost[i][L[i]]; u=gf(u);
return value; if(x[u]==t)return u;
rep(i,0,n) { } // hash-cpp-all = 055ca9687f72b2dd5e2d2c6921f1c51d x[u]=t;
u[i] = cost[i][0]; u= chd[u] ? nex[chd[u]] : 0;
rep(j,1,n) u[i] = min(u[i], cost[i][j]); }
} GeneralMatching.h }
rep(j,0,n) { Description: Matching for general graphs. Fails with probability void lk(int a,int x){
v[j] = cost[0][j] - u[0]; N/mod. while(a!=x){
Time: O N 3

rep(i,1,n) v[j] = min(v[j], cost[i][j] - u[i]); int b=chd[a],c=nex[b];
} "../numerical/MatrixInverse-mod.h" 40 lines if(gf(c)!=x)nex[c]=b;
vector<pii> generalMatching(int N, vector<pii>& ed) { if(fl[b]==2)fl[qu[q++]=b]=1;
L = R = vi(n, -1); vector<vector<ll>> mat(N, vector<ll>(N)), A; if(fl[c]==2)fl[qu[q++]=c]=1;
rep(i,0,n) rep(j,0,n) { trav(pa, ed) { un(a,b);un(b,c);
if (R[j] != -1) continue; int a = pa.first, b = pa.second, r = rand() % mod; a=c;
if (zero(cost[i][j] - u[i] - v[j])) { mat[a][b] = r, mat[b][a] = (mod - r) % mod; }
L[i] = j; } }
R[j] = i; void find(int rt){
mated++; int r = matInv(A = mat), M = 2*N - r, fi, fj; rep(i,1,n+1)nex[i]=fl[i]=0,fa[i]=i;
break; assert(r % 2 == 0); p=q=0;qu[q++]=rt;fl[rt]=1;
} while(p!=q){
} if (M != N) do { int u=qu[p++];
mat.resize(M, vector<ll>(M)); trav(v, g[u]) {
for (; mated < n; mated++) { // until solution is rep(i,0,N) { if(gf(v)==gf(u) || fl[v]==2 || v==chd[u])continue;
,→feasible mat[i].resize(M); if(fl[v]==1){
int s = 0; rep(j,N,M) { int x=lca(u,v);
MIT NULL MinimumVertexCover SCC BiconnectedComponents 2sat 13
if(gf(u)!=x)nex[u]=v; Time: O (E + V ) 24 lines
template<class F>
if(gf(v)!=x)nex[v]=u; void bicomps(F f) {
lk(u,x); vi val, comp, z, cont; num.assign(sz(ed), 0);
lk(v,x); int Time, ncomps; rep(i,0,sz(ed)) if (!num[i]) dfs(i, -1, f);
}else if(!chd[v]){ template<class G, class F> int dfs(int j, G& g, F f) { } // hash-cpp-all = e183ffd0266ca965525c2788c540f8f0
nex[v]=u; int low = val[j] = ++Time, x; z.push_back(j);
while(v){ trav(e,g[j]) if (comp[e] < 0)
u=nex[v]; low = min(low, val[e] ?: dfs(e,g,f));
int t=chd[u];
2sat.h
if (low == val[j]) { Description: Calculates a valid assignment to boolean variables a,
chd[v]=u;chd[u]=v; b, c,... to a 2-SAT problem, so that an expression of the type
v=t; do {
x = z.back(); z.pop_back(); (akkb)&&(!akkc)&&(dkk!b)&&... becomes true, or reports that it is un-
} satisfiable. Negated variables are represented by bit-inversions (∼x).
return; comp[x] = ncomps;
cont.push_back(x); Usage: TwoSat ts(number of boolean variables);
}else{ ts.either(0, ∼3); // Var 0 is true or var 3 is false
nex[v]=u; } while (x != j);
f(cont); cont.clear(); ts.set value(2); // Var 2 is true
fl[v]=2; ts.at most one({0,∼1,2}); // <= 1 of vars 0, ∼1 and 2 are
fl[qu[q++]=chd[v]]=1; ncomps++;
} true
} ts.solve(); // Returns true iff it is solvable
} return val[j] = low;
} ts.values[0..N-1] holds the assigned values to the vars
} Time: O (N + E), where N is the number of boolean variables, and E
} template<class G, class F> void scc(G& g, F f) {
int n = sz(g); is the number of clauses. 57 lines
int run_match(){
memset(chd,0,sizeof(chd)); val.assign(n, 0); comp.assign(n, -1); struct TwoSat {
rep(i,1,n+1)if(!chd[i])find(i); Time = ncomps = 0; int N;
int cnt = 0; rep(i,0,n) if (comp[i] < 0) dfs(i, g, f); vector<vi> gr;
rep(i,1,n+1) cnt += bool(chd[i]); } // hash-cpp-all = 2c7a153ddd31436517cf3ad28efa4ac5 vi values; // 0 = false, 1 = true
return cnt/2;
} // hash-cpp-all = 54d8d95b9dc2053ea903a35ce4928a11 BiconnectedComponents.h TwoSat(int n = 0) : N(n), gr(2*n) {}
Description: Finds all biconnected components in an undirected graph,
and runs a callback for the edges in each. In a biconnected component int add_var() { // (optional)
MinimumVertexCover.h there are at least two distinct paths between any two nodes. Note that a gr.emplace_back();
Description: Finds a minimum vertex cover in a bipartite graph. The gr.emplace_back();
node can be in several components. An edge which is not in a component
size is the same as the size of a maximum matching, and the complement return N++;
is a bridge, i.e., not part of any cycle.
is an independent set. }
Usage: int eid = 0; ed.resize(N);
"DFSMatching.h" 20 lines
for each edge (a,b) {
vi cover(vector<vi>& g, int n, int m) { ed[a].emplace back(b, eid); void either(int f, int j) {
int res = dfs_matching(g, n, m); ed[b].emplace back(a, eid++); } f = max(2*f, -1-2*f);
seen.assign(m, false); bicomps([&](const vi& edgelist) {...}); j = max(2*j, -1-2*j);
vector<bool> lfound(n, true); Time: O (E + V ) gr[fˆ1].push_back(j);
33 lines gr[jˆ1].push_back(f);
trav(it, match) if (it != -1) lfound[it] = false;
vi q, cover; vi num, st; }
rep(i,0,n) if (lfound[i]) q.push_back(i); vector<vector<pii>> ed; void set_value(int x) { either(x, x); }
while (!q.empty()) { int Time;
int i = q.back(); q.pop_back(); template<class F> void at_most_one(const vi& li) { // (optional)
lfound[i] = 1; int dfs(int at, int par, F f) { if (sz(li) <= 1) return;
trav(e, g[i]) if (!seen[e] && match[e] != -1) { int me = num[at] = ++Time, e, y, top = me; int cur = ∼li[0];
seen[e] = true; trav(pa, ed[at]) if (pa.second != par) { rep(i,2,sz(li)) {
q.push_back(match[e]); tie(y, e) = pa; int next = add_var();
} if (num[y]) { either(cur, ∼li[i]);
} top = min(top, num[y]); either(cur, next);
rep(i,0,n) if (!lfound[i]) cover.push_back(i); if (num[y] < me) either(∼li[i], next);
rep(i,0,m) if (seen[i]) cover.push_back(n+i); st.push_back(e); cur = ∼next;
assert(sz(cover) == res); } else { }
return cover; int si = sz(st); either(cur, ∼li[1]);
} // hash-cpp-all = 9eeda105ef373dfc9bd11d0139e4fc82 int up = dfs(y, e, f); }
top = min(top, up);
if (up == me) { vi val, comp, z; int time = 0;
6.4 DFS algorithms st.push_back(e);
f(vi(st.begin() + si, st.end()));
int dfs(int i) {
int low = val[i] = ++time, x; z.push_back(i);
SCC.h st.resize(si); trav(e, gr[i]) if (!comp[e])
Description: Finds strongly connected components in a directed graph. } low = min(low, val[e] ?: dfs(e));
If vertices u, v belong to the same component, we can reach u from v else if (up < me) st.push_back(e); ++time;
and vice versa. else { /* e is a bridge */ } if (low == val[i]) do {
Usage: scc(graph, [&](vi& v) { ... }) visits all } x = z.back(); z.pop_back();
components in reverse topological order. comp[i] holds the } comp[x] = time;
component index of a node (a component only has edges to return top; if (values[x>>1] == -1)
components with lower index). ncomps will contain the } values[x>>1] = !(x&1);
number of components. } while (x != i);
MIT NULL MaximalCliques graph-clique cycle-counting CompressTree 14
return val[i] = low; // step is node id, size is current sol., more is available int w[N];
} ,→ mask, cons is constitution mask int circle3(){ // hash-cpp-1
bool clique::search(int step, int size, int ans=0;
bool solve() { LL more, LL cons) { for (int i = 1; i <= n; i++)
values.assign(N, -1); if (step >= n) { w[i]=0;
val.assign(2*N, 0); comp = val; // a new solution reached
rep(i,0,2*N) if (!comp[i]) dfs(i); this->size = size; for (int x = 1; x <= n; x++) {
rep(i,0,N) if (comp[2*i] == comp[2*i+1]) return 0; this->cons = cons; for(int y:lk[x])w[y]=1;
return 1; return true;
} } for(int y:lk[x])for(int z:lk[y])if(w[z]){
}; // hash-cpp-all = 288fb44b52e9016a30ce849e38390eb9 long long now = ONE << step; ans=(ans+go[x].size()+go[y].size()+go[z].size()-6)%P;
if ((now & more) > 0) { }
long long next = more & mask[step];
6.5 Heuristics if (size + bits[next & MASK] + for(int y:lk[x])w[y]=0;
bits[(next >> 21) & MASK] + }
MaximalCliques.h bits[next >> 42] >= this->size return ans;
Description: Runs a callback for all maximal cliques in a graph (given && size + cmax[step] > this->size) { } // hash-cpp-1 = 719dcec935e20551fd984c12c3bfa3ba
as a symmetric bitset matrix; self-edges not allowed). Possible optimiza- // the current node is in the clique
tion: on the top-most recursion level, ignore ’cands’, and go through if (search(step+1,size+1,next,cons|now)) int deg[N], pos[N], id[N];
nodes in order of increasing degree, where degrees go down as nodes are return true;
removed.   } int circle4(){ // hash-cpp-2
Time: O 3n/3 , much faster for sparse graphs } for (int i = 1; i <= n; i++)
12 lines
long long next = more & ∼now; w[i]=0;
typedef bitset<128> B;
if (size + bits[next & MASK] + int ans=0;
template<class F>
bits[(next >> 21) & MASK] + for (int x = 1; x <= n; x++) {
void cliques(vector<B>& eds, F f, B P = ∼B(), B X={}, B R
bits[next >> 42] > this->size) { for(int y:go[x])for(int z:lk[y])if(pos[z]>pos[x]){
,→={}) {
// the current node is not in the clique ans=(ans+w[z])%P;
if (!P.any()) { if (!X.any()) f(R); return; }
if (search(step + 1, size, next, cons)) w[z]++;
auto q = (P | X)._Find_first();
return true; }
auto cands = P & ∼eds[q];
} for(int y:go[x])for(int z:lk[y])w[z]=0;
rep(i,0,sz(eds)) if (cands[i]) {
return false; }
R[i] = 1;
} return ans;
cliques(eds, f, P & eds[i], X & eds[i], R);
// solve maximum clique and return size } // hash-cpp-2 = 39b3aaf47e9fdc4dfff3fdfdf22d3a8e
R[i] = P[i] = 0; X[i] = 1;
int clique::sizeClique(vector<vector<int> >& mat) {
}
n = mat.size(); inline bool cmp(const int &x,const int &y){
} // hash-cpp-all = b0d5b15b7ebdcde7ff57f0761c050583
// generate mask vectors return deg[x]<deg[y];
for (int i = 0; i < n; ++i) { }
graph-clique.cpp mask[i] = 0;
Description: Max clique N<64. Bit trick for speed. clique solver cal- for (int j = 0; j < n; ++j) void init() {
culates both size and consitution of maximum clique uses bit operation if (mat[i][j] > 0) mask[i] |= ONE << j; scanf("%d%d", &n, &m);
to accelerate searching graph size limit is 63, the graph should be undi- } for (int i = 1; i <= n; i++)
rected can optimize to calculate on each component, and sort on vertex size = 0; deg[i] = 0, go[i].clear(), lk[i].clear();;
degrees can be used to solve maximum independent set for (int i = n - 1; i >= 0; --i) { while (m--) {
80 lines search(i + 1, 1, mask[i], ONE << i); int a,b;
class clique { cmax[i] = size; scanf("%d%d",&a,&b);
public: } deg[a]++;deg[b]++;
static const long long ONE = 1; return size; go[a].push_back(b);go[b].push_back(a);
static const long long MASK = (1 << 21) - 1; } }
char* bits; // calls sizeClique and restore cons for (int i = 1; i <= n; i++)
int n, size, cmax[63]; vector<int> clique::getClq( id[i] = i;
long long mask[63], cons; vector<vector<int> >& mat) { sort(id+1,id+1+n,cmp);
// initiate lookup table sizeClique(mat); for (int i = 1; i <= n; i++) pos[id[i]]=i;
clique() { vector<int> ret; for (int x = 1; x <= n; x++)
bits = new char[1 << 21]; for (int i = 0; i < n; ++i) for(int y:go[x])
bits[0] = 0; if ((cons&(ONE<<i)) > 0) ret.push_back(i); if(pos[y]>pos[x])lk[x].push_back(y);
for (int i = 1; i < (1<<21); ++i) return ret; }
bits[i] = bits[i >> 1] + (i & 1); } // hash-cpp-all = fbf6cf3d9cbb4f5d32d6245cfbe40fd0
}
∼clique() {
cycle-counting.cpp
6.6 Trees
delete bits;
} Description: Counts 3 and 4 cycles CompressTree.h
// search routine <bits/stdc++.h> 62 lines Description: Given a rooted tree and a subset S of nodes, compute
bool search(int step,int siz,LL mor,LL con); #define P 1000000007 the minimal subtree that contains all the nodes by adding all (at most
// solve maximum clique and return size #define N 110000 |S| − 1) pairwise LCA’s and compressing edges. Returns a list of (par,
int sizeClique(vector<vector<int> >& mat); orig index) representing a tree rooted at 0. The root points to itself.
// solve maximum clique and return set int n, m; Time: O (|S| log |S|)
vector<int>getClq(vector<vector<int> >&mat); vector <int> go[N], lk[N]; "LCA.h" 20 lines

}; vpi compressTree(LCA& lca, const vi& subset) {


MIT NULL MatrixTree directed-MST graph-dominator-tree 15
static vi rev; rev.resize(sz(lca.dist)); int cnt = 0;
vi li = subset, &T = lca.time; rep(i, NV) { void compress(int now) { // hash-cpp-2
auto cmp = [&](int a, int b) { return T[a] < T[b]; }; ID[i] = -1; if(anc[anc[now]] != 0) {
sort(all(li), cmp); vis[i] = -1; compress(anc[now]);
int m = sz(li)-1; } if(semi[best[now]] > semi[best[anc[now]]])
rep(i,0,m) { In[root] = 0; best[now] = best[anc[now]];
int a = li[i], b = li[i+1]; anc[now] = anc[anc[now]];
li.push_back(lca.query(a, b)); rep(i, NV) { }
} ret += In[i]; } // hash-cpp-2 = 1c9444eb3f768b7af8741fafbf3afb5a
sort(all(li), cmp); int v = i;
li.erase(unique(all(li)), li.end()); while(vis[v] != i && ID[v] == -1 && v != root) inline int eval(int now) { // hash-cpp-3
rep(i,0,sz(li)) rev[li[i]] = i; ,→{ if(anc[now] == 0)
vpi ret = {pii(0, li[0])}; vis[v] = i; return now;
rep(i,0,sz(li)-1) { v = pre[v]; else {
int a = li[i], b = li[i+1]; } compress(now);
ret.emplace_back(rev[lca.query(a, b)], b); if(v != root && ID[v] == -1) { return semi[best[anc[now]]] >= semi[best[now]] ? best[
} for(u = pre[v]; u != v; u = pre[u]) { ,→now]
return ret; ID[u] = cnt; : best[anc[now]];
} // hash-cpp-all = dabd7520dba8306be5675979add23011 } }
ID[v] = cnt++; } // hash-cpp-3 = 4e235f39666315b46dcd3455d5f866d1
}
MatrixTree.h } inline void link(int v, int w) { // hash-cpp-4
Description: To count the number of spanning trees in an undirected if(cnt == 0) break; int s = w;
graph G: create an N × N matrix mat, and for each edge (a, b) ∈ G, do rep(i, NV) { while(semi[best[w]] < semi[best[child[w]]]) {
mat[a][a]++, mat[b][b]++, mat[a][b]--, mat[b][a]--. Remove if(ID[i] == -1) ID[i] = cnt++; if(size[s] + size[child[child[s]]] >= 2*size[child[s]])
the last row and column, and take the determinant. 1 lines } ,→ {
// hash-cpp-all = d41d8cd98f00b204e9800998ecf8427e rep(i, NE) { anc[child[s]] = s;
v = E_copy[i].v; child[s] = child[child[s]];
E_copy[i].u = ID[E_copy[i].u]; } else {
6.7 Other E_copy[i].v = ID[E_copy[i].v]; size[child[s]] = size[s];
directed-MST.cpp if(E_copy[i].u != E_copy[i].v) { s = anc[s] = child[s];
Description: Finds the minimum spanning arborescence from the root. E_copy[i].cost -= In[v]; }
(any more notes?) } }
73 lines } best[s] = best[w];
#define rep(i, n) for (int i = 0; i < n; i++) NV = cnt; size[v] += size[w];
root = ID[root]; if(size[v] < 2*size[w])
#define N 110000 } swap(s, child[v]);
#define M 110000 return ret; while(s != 0) {
#define inf 2000000000 } anc[s] = v;
// hash-cpp-all = 84815c2bfececf3575ecf663c0703643 s = child[s];
struct edg { }
int u, v; } // hash-cpp-4 = 270548fd021351ae21e97878f367b6f9
int cost; graph-dominator-tree.cpp
} E[M], E_copy[M]; Description: Dominator Tree. // idom[n] and other vertices that cannot be reached from n
107 lines ,→ will be 0
int In[N], ID[N], vis[N], pre[N]; #define N 110000 //max number of vertices void lengauer_tarjan(int n) { // n is the root’s number //
,→hash-cpp-5
// edges pointed from root. vector<int> succ[N], prod[N], bucket[N], dom_t[N]; memset(dfn, -1, sizeof dfn);
int Directed_MST(int root, int NV, int NE) { int semi[N], anc[N], idom[N], best[N], fa[N], tmp_idom[N]; memset(fa, -1, sizeof fa);
for (int i = 0; i < NE; i++) int dfn[N], redfn[N]; timestamp = 0;
E_copy[i] = E[i]; int child[N], size[N]; dfs(n);
int ret = 0; int timestamp; fa[1] = 0;
int u, v; for(int w = timestamp; w > 1; --w) {
while (true) { void dfs(int now) { // hash-cpp-1 int sz = prod[w].size();
rep(i, NV) In[i] = inf; dfn[now] = ++timestamp; for(int i = 0; i < sz; ++i) {
rep(i, NE) { redfn[timestamp] = now; int u = eval(prod[w][i]);
u = E_copy[i].u; anc[timestamp] = idom[timestamp] = child[timestamp] = if(semi[w] > semi[u])
v = E_copy[i].v; ,→size[timestamp] = 0; semi[w] = semi[u];
if(E_copy[i].cost < In[v] && u != v) { semi[timestamp] = best[timestamp] = timestamp; }
In[v] = E_copy[i].cost; int sz = succ[now].size(); bucket[semi[w]].push_back(w);
pre[v] = u; for(int i = 0; i < sz; ++i) { //anc[w] = fa[w]; link operation for o(mlogm) version
} if(dfn[succ[now][i]] == -1) { link(fa[w], w);
} dfs(succ[now][i]); if(fa[w] == 0)
rep(i, NV) { fa[dfn[succ[now][i]]] = dfn[now]; continue;
if(i == root) continue; } sz = bucket[fa[w]].size();
if(In[i] == inf) return -1; // no solution prod[dfn[succ[now][i]]].push_back(dfn[now]); for(int i = 0; i < sz; ++i) {
} } int u = eval(bucket[fa[w]][i]);
} // hash-cpp-1 = 6412bfd6a0d21b66ddaa51ea79cbe7bd if(semi[u] < fa[w])
MIT NULL graph-negative-cycle Point lineDistance SegmentDistance SegmentIntersection SegmentIntersectionQ 16
idom[bucket[fa[w]][i]] = u; 7.1 Geometric primitives SegmentIntersection.h
else Description:
idom[bucket[fa[w]][i]] = fa[w]; Point.h If a unique intersection point between the line segments
} Description: Class to handle points in the plane. T can be e.g. double going from s1 to e1 and from s2 to e2 exists r1 is set to this
bucket[fa[w]].clear(); or long long. (Avoid int.) 25 lines point and 1 is returned. If no intersection point exists 0 is
} returned and if infinitely many exists 2 is returned and r1 e1
template<class T>
for(int w = 2; w <= timestamp; ++w) { and r2 are set to the two ends of the common line. The e2
struct Point {
if(idom[w] != semi[w]) typedef Point P; wrong position will be returned if P is Point<int> and r1
idom[w] = idom[idom[w]]; the intersection point does not have integer coordinates. s1 s2
T x, y;
} Products of three coordinates are used in intermediate
explicit Point(T x=0, T y=0) : x(x), y(y) {}
idom[1] = 0; steps so watch out for overflow if using int or long long.
bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y
for(int i = timestamp; i > 1; --i) { Use segmentIntersectionQ to get just a true/false answer.
,→); }
if(fa[i] == -1) Usage: Point<double> intersection, dummy;
bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y
continue; if (segmentIntersection(s1,e1,s2,e2,intersection,dummy)==1)
,→); }
dom_t[idom[i]].push_back(i); cout << "segments intersect at " << intersection <<
P operator+(P p) const { return P(x+p.x, y+p.y); }
} endl;
P operator-(P p) const { return P(x-p.x, y-p.y); }
memset(tmp_idom, 0, sizeof tmp_idom); "Point.h" 27 lines
P operator*(T d) const { return P(x*d, y*d); }
for (int i = 1; i <= timestamp; i++) P operator/(T d) const { return P(x/d, y/d); } template<class P>
tmp_idom[redfn[i]] = redfn[idom[i]]; T dot(P p) const { return x*p.x + y*p.y; } int segmentIntersection(const P& s1, const P& e1,
memcpy(idom, tmp_idom, sizeof idom); T cross(P p) const { return x*p.y - y*p.x; } const P& s2, const P& e2, P& r1, P& r2) {
} // hash-cpp-5 = f49c40461d92222d8d39b28b0de66828 T cross(P a, P b) const { return (a-*this).cross(b-*this) if (e1==s1) {
,→; } if (e2==s2) {
T dist2() const { return x*x + y*y; } if (e1==e2) { r1 = e1; return 1; } //all equal
double dist() const { return sqrt((double)dist2()); } else return 0; //different point segments
// angle to x-axis in interval [-pi, pi] } else return segmentIntersection(s2,e2,s1,e1,r1,r2);//
double angle() const { return atan2(y, x); } ,→swap
graph-negative-cycle.cpp P unit() const { return *this/dist(); } // makes dist()=1 }
Description: negative cycle 33 lines //segment directions and separation
P perp() const { return P(-y, x); } // rotates +90
double b[N][N]; ,→degrees P v1 = e1-s1, v2 = e2-s2, d = s2-s1;
P normal() const { return perp().unit(); } auto a = v1.cross(v2), a1 = v1.cross(d), a2 = v2.cross(d)
double dis[N]; // returns point rotated ’a’ radians ccw around the ,→;
int vis[N], pc[N]; ,→origin if (a == 0) { //if parallel
P rotate(double a) const { auto b1=s1.dot(v1), c1=e1.dot(v1),
bool dfs(int k) { return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); } b2=s2.dot(v1), c2=e2.dot(v1);
vis[k] += 1; pc[k] = true; }; // hash-cpp-all = f698493d48eeeaa76063407bf935b5a3 if (a1 || a2 || max(b1,min(b2,c2))>min(c1,max(b2,c2)))
if (vis[k] > N) return 0;
return true; r1 = min(b2,c2)<b1 ? s1 : (b2<c2 ? s2 : e2);
for (int i = 0; i < N; i++) lineDistance.h r2 = max(b2,c2)>c1 ? e1 : (b2>c2 ? s2 : e2);
if (dis[k] + b[k][i] < dis[i]) { Description: return 2-(r1==r2);
Returns the signed distance between point p and the line }
dis[i] = dis[k] + b[k][i];
containing points a and b. Positive value on left side and
if (!pc[i]) { res if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
negative on right as seen from a towards b. a==b gives if (0<a1 || a<-a1 || 0<a2 || a<-a2)
if (dfs(i))
nan. P is supposed to be Point<T> or Point3D<T> e p return 0;
return true;
where T is e.g. double or long long. It uses products in r1 = s1-v1*a2/a;
} else return true;
intermediate steps so watch out for overflow if using int or return 1;
long long. Using Point3D will always give a non-negative s
}
pc[k] = false; } // hash-cpp-all = 1181b7cc739b442c29bada6b0d73a550
distance.
return false; "Point.h" 4 lines
} template<class P> SegmentIntersectionQ.h
double lineDist(const P& a, const P& b, const P& p) { Description: Like segmentIntersection, but only returns true/false.
bool chk(double d) { return (double)(b-a).cross(p-a)/(b-a).dist(); Products of three coordinates are used in intermediate steps so watch
for (int i = 0; i < N; i ++) } // hash-cpp-all = f6bf6b556d99b09f42b86d28d1eaa86d out for overflow if using int or long long.
for (int j = 0; j < N; j ++) { "Point.h" 16 lines

e res p
b[i][j] = -a[i][j] + d;
} SegmentDistance.h template<class P>
for (int i = 0; i < N; i++) Description: bool segmentIntersectionQ(P s1, P e1, P s2, P e2) {
vis[i] = false, dis[i] = 0, pc[i] = false; Returns the shortest distance between point p and the if (e1 == s1) {
for (int i = 0; i < N; i++) line segment from point s to e. s if (e2 == s2) return e1 == e2;
if (!vis[i] && dfs(i)) Usage: Point<double> a, b(2,2), p(1,1); swap(s1,s2); swap(e1,e2);
return true; bool onSegment = segDist(a,b,p) < 1e-10; }
return false; "Point.h" 6 lines P v1 = e1-s1, v2 = e2-s2, d = s2-s1;
} // hash-cpp-all = ec5cf9bc61e058959ce8649f1e707b1b auto a = v1.cross(v2), a1 = d.cross(v1), a2 = d.cross(v2)
typedef Point<double> P;
,→;
double segDist(P& s, P& e, P& p) {
if (a == 0) { // parallel
if (s==e) return (p-s).dist();
auto b1 = s1.dot(v1), c1 = e1.dot(v1),
auto d = (e-s).dist2(), t = min(d,max(.0,(p-s).dot(e-s)))
b2 = s2.dot(v1), c2 = e2.dot(v1);
,→;
return !a1 && max(b1,min(b2,c2)) <= min(c1,max(b2,c2));
return ((p-s)*d-(e-s)*t).dist()/d;
}
Geometry (7) } // hash-cpp-all = 5c88f46fb14a05a4f47bbd23b8a9c427
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
MIT NULL lineIntersection sideOf onSegment linearTransformation Angle angleCmp CircleIntersection circleTangents 17
r p1
return (0 <= a1 && a1 <= a && 0 <= a2 && a2 <= a); linearTransformation.h angleCmp.h
} // hash-cpp-all = 1ff4ba22bd0aefb04bf48cca4d6a7d8c Description: Description: Useful utilities for dealing with angles of rays from origin.
p0 res
OK for integers, only uses cross product. Doesn’t support (0,0). 22 lines
Apply the linear transformation (translation, rotation and q0
scaling) which takes line p0-p1 to line q0-q1 to point r. q1 template <class P>
lineIntersection.h "Point.h" 6 lines bool sameDir(P s, P t) {
Description: typedef Point<double> P; return s.cross(t) == 0 && s.dot(t) > 0;
If a unique intersection point of the lines going through P linearTransformation(const P& p0, const P& p1, }
s1,e1 and s2,e2 exists r is set to this point and 1 is re- const P& q0, const P& q1, const P& r) { // checks 180 <= s..t < 360?
turned. If no intersection point exists 0 is returned and if P dp = p1-p0, dq = q1-q0, num(dp.cross(dq), dp.dot(dq)); template <class P>
infinitely many exists -1 is returned. If s1==e1 or s2==e2 e2 r return q0 + P((r-p0).cross(num), (r-p0).dot(num))/dp. bool isReflex(P s, P t) {
-1 is returned. The wrong position will be returned if P is ,→dist2(); auto c = s.cross(t);
Point<int> and the intersection point does not have in- e1 s2 } // hash-cpp-all = 03a3061b3ef024b4e29ea06169932b21 return c ? (c < 0) : (s.dot(t) < 0);
teger coordinates. Products of three coordinates are used s1 }
in intermediate steps so watch out for overflow if using // operator < (s,t) for angles in [base,base+2pi)
int or long long. template <class P>
Usage: point<double> intersection; Angle.h bool angleCmp(P base, P s, P t) {
if (1 == LineIntersection(s1,e1,s2,e2,intersection)) Description: A class for ordering angles (as represented by int points int r = isReflex(base, s) - isReflex(base, t);
cout << "intersection point at " << intersection << and a number of rotations around the origin). Useful for rotational return r ? (r < 0) : (0 < s.cross(t));
endl; sweeping. Sometimes also represents points or vectors. }
"Point.h" 9 lines Usage: vector<Angle> v = {w[0], w[0].t360() ...}; // // is x in [s,t] taken ccw? 1/0/-1 for in/border/out
template<class P> sorted template <class P>
int lineIntersection(const P& s1, const P& e1, const P& s2, int j = 0; rep(i,0,n) { while (v[j] < v[i].t180()) ++j; } int angleBetween(P s, P t, P x) {
const P& e2, P& r) { // sweeps j such that (j-i) represents the number of if (sameDir(x, s) || sameDir(x, t)) return 0;
if ((e1-s1).cross(e2-s2)) { //if not parallell positively oriented triangles with vertices at 0 and i37 lines return angleCmp(s, x, t) ? 1 : -1;
r = s2-(e2-s2)*(e1-s1).cross(s2-s1)/(e1-s1).cross(e2-s2 } // hash-cpp-all = 6edd25f30f9c69989bbd2115b4fdceda
struct Angle {
,→); int x, y;
return 1;
} else
int t;
Angle(int x, int y, int t=0) : x(x), y(y), t(t) {}
7.2 Circles
return -((e1-s1).cross(s2-s1)==0 || s2==e2);
} // hash-cpp-all = aa1f17f0dbde5177e697038a420bb078
Angle operator-(Angle b) const { return {x-b.x, y-b.y, t CircleIntersection.h
,→}; } Description: Computes a pair of points at which two circles intersect.
int quad() const { Returns false in case of no intersection.
assert(x || y); "Point.h" 14 lines
if (y < 0) return (x >= 0) + 2;
sideOf.h if (y > 0) return (x <= 0);
typedef Point<double> P;
Description: Returns where p is as seen from s towards e. 1/0/-1 ⇔ bool circleIntersection(P a, P b, double r1, double r2,
return (x <= 0) * 2; pair<P, P>* out) {
left/on line/right. If the optional argument eps is given 0 is returned if
} P delta = b - a;
p is within distance eps from the line. P is supposed to be Point<T>
Angle t90() const { return {-y, x, t + (quad() == 3)}; } assert(delta.x || delta.y || r1 != r2);
where T is e.g. double or long long. It uses products in intermediate
Angle t180() const { return {-x, -y, t + (quad() >= 2)}; if (!delta.x && !delta.y) return false;
steps so watch out for overflow if using int or long long.
,→} double r = r1 + r2, d2 = delta.dist2();
Usage: bool left = sideOf(p1,p2,q)==1;
Angle t360() const { return {x, y, t + 1}; } double p = (d2 + r1*r1 - r2*r2) / (2.0 * d2);
"Point.h" 11 lines
}; double h2 = r1*r1 - p*p*d2;
template<class P> bool operator<(Angle a, Angle b) {
int sideOf(const P& s, const P& e, const P& p) { if (d2 > r*r || h2 < 0) return false;
// add a.dist2() and b.dist2() to also compare distances P mid = a + delta*p, per = delta.perp() * sqrt(h2 / d2);
auto a = (e-s).cross(p-s); return make_tuple(a.t, a.quad(), a.y * (ll)b.x) <
return (a > 0) - (a < 0); make_tuple(b.t, b.quad(), a.x * (ll)b.y); *out = {mid + per, mid - per};
} return true;
} } // hash-cpp-all = 828fbb1fff1469ed43b2284c8e07a06c
template<class P>
int sideOf(const P& s, const P& e, const P& p, double eps) // Given two points, this calculates the smallest angle
,→{ ,→between
auto a = (e-s).cross(p-s); // them, i.e., the angle that covers the defined line
circleTangents.h
double l = (e-s).dist()*eps; Description:
,→segment.
return (a > l) - (a < -l); pair<Angle, Angle> segmentAngles(Angle a, Angle b) { Returns a pair of the two points on the circle with radius r second
} // hash-cpp-all = 2eb6fe62d7f3750fd3a0ec3d91329ed6 centered around c whos tangent lines intersect p. If p lies r
if (b < a) swap(a, b);
within the circle NaN-points are returned. P is intended c
return (b < a.t180() ?
to be Point<double>. The first point is the one to the
make_pair(a, b) : make_pair(b, a.t360())); p first
} right as seen from the p towards c.
onSegment.h Angle operator+(Angle a, Angle b) { // point a + vector b Usage: typedef Point<double> P;
Description: Returns true iff p lies on the line segment from s to e. Angle r(a.x + b.x, a.y + b.y, a.t); pair<P,P> p = circleTangents(P(100,2),P(0,0),2);
Intended for use with e.g. Point<long long> where overflow is an issue. if (a.t180() < r) r.t--; "Point.h" 6 lines
Use (segDist(s,e,p)<=epsilon) instead when using Point<double>. return r.t180() < a ? r.t360() : r; template<class P>
"Point.h" 5 lines } pair<P,P> circleTangents(const P &p, const P &c, double r)
template<class P> Angle angleDiff(Angle a, Angle b) { // angle b - angle a ,→{
bool onSegment(const P& s, const P& e, const P& p) { int tu = b.t - a.t; a.t = b.t; P a = p-c;
P ds = p-s, de = p-e; return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x, tu - (b < a double x = r*r/a.dist2(), y = sqrt(x-x*x);
return ds.cross(de) == 0 && ds.dot(de) <= 0; ,→)}; return make_pair(c+a*x+a.perp()*y, c+a*x-a.perp()*y);
} // hash-cpp-all = 0b2b1c6866c98c2d2003acec0701e693 } // hash-cpp-all = 1856c5d371c2f8f342a22615fa92cd54 } // hash-cpp-all = b70bc575e85c140131116e64926b4ce1
MIT circumcircle
NULL MinimumEnclosingCircle insidePolygon PolygonArea PolygonCenter PolygonCut ConvexHull PolygonDiameter PointInsideHull 18
circumcircle.h Usage: typedef Point<int> pi; }
Description: vector<pi> v; v.push back(pi(4,4)); if (side)
The circumcirle of a triangle is the circle intersecting all B v.push back(pi(1,2)); v.push back(pi(2,1)); res.push_back(cur);
three vertices. ccRadius returns the radius of the circle r c bool in = insidePolygon(v.begin(),v.end(), pi(3,4), false); }
going through points A, B and C and ccCenter returns C Time: O (n) return res;
the center of the same circle. A "Point.h", "onSegment.h", "SegmentDistance.h" 14 lines } // hash-cpp-all = acf5106be46aa8f6f5d7a8d0ffdaae3c
"Point.h" 9 lines template<class It, class P>
bool insidePolygon(It begin, It end, const P& p,
typedef Point<double> P;
double ccRadius(const P& A, const P& B, const P& C) {
bool strict = true) { ConvexHull.h
int n = 0; //number of isects with line from p to (inf,p. Description:
return (B-A).dist()*(C-B).dist()*(A-C).dist()/
,→y) Returns a vector of indices of the convex hull in counter-
abs((B-A).cross(C-A))/2;
for (It i = begin, j = end-1; i != end; j = i++) { clockwise order. Points on the edge of the hull between
}
//if p is on edge of polygon two other points are not considered part of the hull.
P ccCenter(const P& A, const P& B, const P& C) {
if (onSegment(*i, *j, p)) return !strict; Usage: vector<P> ps, hull;
P b = C-A, c = B-A;
//or: if (segDist(*i, *j, p) <= epsilon) return !strict trav(i, convexHull(ps)) hull.push back(ps[i]);
return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2;
,→; Time: O (n log n)
} // hash-cpp-all = 1caa3aea364671cb961900d4811f0282
//increment n if segment intersects line from p "Point.h" 20 lines
n += (max(i->y,j->y) > p.y && min(i->y,j->y) <= p.y && typedef Point<ll> P;
((*j-*i).cross(p-*i) > 0) == (i->y <= p.y)); pair<vi, vi> ulHull(const vector<P>& S) {
MinimumEnclosingCircle.h } vi Q(sz(S)), U, L;
Description: Computes the minimum circle that encloses a set of return n&1; //inside if odd number of intersections iota(all(Q), 0);
points. } // hash-cpp-all = 0cadec56a74f257b8d1b25f56ba7ebad sort(all(Q), [&S](int a, int b){ return S[a] < S[b]; });
Time: expected O (n) trav(it, Q) {
"circumcircle.h" 28 lines #define ADDP(C, cmp) while (sz(C) > 1 && S[C[sz(C)-2]].
PolygonArea.h ,→cross(\
pair<double, P> mec2(vector<P>& S, P a, P b, int n) { Description: Returns twice the signed area of a polygon. Clockwise
double hi = INFINITY, lo = -hi; enumeration gives negative area. Watch out for overflow if using int as S[it], S[C.back()]) cmp 0) C.pop_back(); C.push_back(it);
rep(i,0,n) { T! ADDP(U, <=); ADDP(L, >=);
auto si = (b-a).cross(S[i]-a); "Point.h" 6 lines
}
if (si == 0) continue; return {U, L};
template<class T> }
P m = ccCenter(a, b, S[i]);
T polygonArea2(vector<Point<T>>& v) {
auto cr = (b-a).cross(m-a);
T a = v.back().cross(v[0]); vi convexHull(const vector<P>& S) {
if (si < 0) hi = min(hi, cr);
rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]); vi u, l; tie(u, l) = ulHull(S);
else lo = max(lo, cr);
return a; if (sz(S) <= 1) return u;
}
} // hash-cpp-all = f123003799a972c1292eb0d8af7e37da if (S[u[0]] == S[u[1]]) return {0};
double v = (0 < lo ? lo : hi < 0 ? hi : 0);
P c = (a + b) / 2 + (b - a).perp() * v / (b - a).dist2(); l.insert(l.end(), u.rbegin()+1, u.rend()-1);
return {(a - c).dist2(), c}; PolygonCenter.h return l;
} Description: Returns the center of mass for a polygon. } // hash-cpp-all = d1b691dc7571b8460911ebe2e4023806
pair<double, P> mec(vector<P>& S, P a, int n) { "Point.h" 10 lines
random_shuffle(S.begin(), S.begin() + n); typedef Point<double> P;
P b = S[0], c = (a + b) / 2; Point<double> polygonCenter(vector<P>& v) { PolygonDiameter.h
double r = (a - c).dist2(); auto i = v.begin(), end = v.end(), j = end-1; Description: Calculates the max squared distance of a set of points.
rep(i,1,n) if ((S[i] - c).dist2() > r * (1 + 1e-8)) { Point<double> res{0,0}; double A = 0; "ConvexHull.h" 19 lines
tie(r,c) = (n == sz(S) ? for (; i != end; j=i++) {
mec(S, S[i], i) : mec2(S, a, S[i], i)); vector<pii> antipodal(const vector<P>& S, vi& U, vi& L) {
res = res + (*i + *j) * j->cross(*i); vector<pii> ret;
} A += j->cross(*i);
return {r, c}; int i = 0, j = sz(L) - 1;
} while (i < sz(U) - 1 || j > 0) {
} return res / A / 3;
pair<double, P> enclosingCircle(vector<P> S) { ret.emplace_back(U[i], L[j]);
} // hash-cpp-all = d210bd2372832f7d074894d904e548ab if (j == 0 || (i != sz(U)-1 && (S[L[j]] - S[L[j-1]])
assert(!S.empty()); auto r = mec(S, S[0], sz(S));
return {sqrt(r.first), r.second}; .cross(S[U[i+1]] - S[U[i]]) > 0)) ++i;
} // hash-cpp-all = 9bf427c9626a72f805196e0b7075bda2 PolygonCut.h e else --j;
}
Description:
return ret;
Returns a vector with the vertices of a polygon with ev-
}
erything to the left of the line going from s to e cut away.
7.3 Polygons Usage: vector<P> p = ...; s pii polygonDiameter(const vector<P>& S) {
p = polygonCut(p, P(0,0), P(1,0)); vi U, L; tie(U, L) = ulHull(S);
insidePolygon.h "Point.h", "lineIntersection.h" 15 lines
pair<ll, pii> ans;
Description: Returns true if p lies within the polygon described by typedef Point<double> P; trav(x, antipodal(S, U, L))
the points between iterators begin and end. If strict false is returned vector<P> polygonCut(const vector<P>& poly, P s, P e) { ans = max(ans, {(S[x.first] - S[x.second]).dist2(), x})
when p is on the edge of the polygon. Answer is calculated by counting vector<P> res; ,→;
the number of intersections between the polygon and a line going from rep(i,0,sz(poly)) { return ans.second;
p to infinity in the positive x-direction. The algorithm uses products in P cur = poly[i], prev = i ? poly[i-1] : poly.back(); } // hash-cpp-all = 5596d386362874d2ebcf13cdb142574d
intermediate steps so watch out for overflow. If points within epsilon bool side = s.cross(e, cur) < 0;
from an edge should be considered as on the edge replace the line ”if if (side != (s.cross(e, prev) < 0)) {
(onSegment...” with the comment bellow it (this will cause overflow for res.emplace_back();
int and long long). lineIntersection(s, e, cur, prev, res.back()); PointInsideHull.h
MIT NULL LineHullIntersection halfPlane closestPair 19
Description: Determine whether a point t lies inside a given polygon int bs(P dir) { }
(counter-clockwise order). The polygon must be such that every point int lo = -1, hi = N; };
on the circumference is visible from the first point in the vector. It re- while (hi - lo > 1) {
turns 0 for points outside, 1 for points on the circumference, and 2 for int mid = (lo + hi) / 2; template<class T>
points inside. if (make_pair(qd(dir), dir.y * a[mid].first.x) < bool mycmp(Point<T> a, Point<T> b) {
Time: O (log N ) make_pair(qd(a[mid].first), dir.x * a[mid].first.y) // return atan2(a.y, a.x) < atan2(b.y, b.x);
"Point.h", "sideOf.h", "onSegment.h" 22 lines ,→) if (a.x * b.x < 0) return a.x < 0;
typedef Point<ll> P; hi = mid; if (abs(a.x) < eps) {
int insideHull2(const vector<P>& H, int L, int R, const P& else lo = mid; if (abs(b.x) < eps) return a.y > 0 && b.y < 0;
,→p) { } if (b.x < 0) return a.y > 0;
int len = R - L; return a[hi%N].second; if (b.x > 0) return true;
if (len == 2) { } }
int sa = sideOf(H[0], H[L], p); if (abs(b.x) < eps) {
int sb = sideOf(H[L], H[L+1], p); bool isign(P a, P b, int x, int y, int s) { if (a.x < 0) return b.y < 0;
int sc = sideOf(H[L+1], H[0], p); return sgn(a.cross(p[x], b)) * sgn(a.cross(p[y], b)) == if (a.x > 0) return false;
if (sa < 0 || sb < 0 || sc < 0) return 0; ,→ s; }
if (sb==0 || (sa==0 && L == 1) || (sc == 0 && R == sz(H } return a.cross(b) > 0;
,→))) }
return 1; int bs2(int lo, int hi, P a, P b) {
return 2; int L = lo; bool cmp(Line a, Line b) {
} if (hi < lo) hi += N; return mycmp(a.dir(), b.dir());
int mid = L + len / 2; while (hi - lo > 1) { }
if (sideOf(H[0], H[mid], p) >= 0) int mid = (lo + hi) / 2;
return insideHull2(H, mid, R, p); if (isign(a, b, mid, L, -1)) hi = mid; double Intersection_Area(vector <Line> b) {
return insideHull2(H, L, mid+1, p); else lo = mid; sort(b.begin(), b.end(), cmp);
} } int n = b.size();
return lo; int q = 1, h = 0, i;
int insideHull(const vector<P>& hull, const P& p) { } vector <Line> c(b.size() + 10);
if (sz(hull) < 3) return onSegment(hull[0], hull.back(), for (i = 0; i < n; i++) {
,→p); pii isct(P a, P b) { while (q < h && b[i].out(c[h].intpo(c[h - 1]))) h--;
else return insideHull2(hull, 1, sz(hull), p); int f = bs(a - b), j = bs(b - a); while (q < h && b[i].out(c[q].intpo(c[q + 1]))) q++;
} // hash-cpp-all = 1c16dba23109ced37b95769a3f1d19b7 if (isign(a, b, f, j, 1)) return {-1, -1}; c[++h] = b[i];
int x = bs2(f, j, a, b)%N, if (q < h && abs(c[h].dir().cross(c[h - 1].dir())) <
y = bs2(j, f, a, b)%N; ,→eps) {
LineHullIntersection.h if (a.cross(p[x], b) == 0 && h--;
Description: Line-convex polygon intersection. The polygon must be a.cross(p[x+1], b) == 0) return {x, x}; if (b[i].out(c[h].P1)) c[h] = b[i];
ccw and have no colinear points. isct(a, b) returns a pair describing if (a.cross(p[y], b) == 0 && }
the intersection of a line with the polygon: • (−1, −1) if no collision, a.cross(p[y+1], b) == 0) return {y, y}; }
• (i, −1) if touching the corner i, • (i, i) if along side (i, i + 1), • (i, j) if (a.cross(p[f], b) == 0) return {f, -1}; while (q < h - 1 && c[q].out(c[h].intpo(c[h - 1]))) h--;
if crossing sides (i, i + 1) and (j, j + 1). In the last case, if a corner i is if (a.cross(p[j], b) == 0) return {j, -1}; while (q < h - 1 && c[h].out(c[q].intpo(c[q + 1]))) q++;
crossed, this is treated as happening on side (i, i + 1). The points are return {x, y}; // Intersection is empty. This is sometimes different
returned in the same order as the line hits the polygon. } ,→from the case when
Time: O (N + Q log n) }; // hash-cpp-all = 79decd52fd801714ccebbaa6ab36151e // the intersection area is 0.
"Point.h" 63 lines if (h - q <= 1) return 0;
ll sgn(ll a) { return (a > 0) - (a < 0); } c[h + 1] = c[q];
typedef Point<ll> P; halfPlane.h vector <P> s;
struct HullIntersection { Description: Halfplane intersection area for (i = q; i <= h; i++) s.push_back(c[i].intpo(c[i +
int N; "Point.h", "lineIntersection.h" 70 lines ,→1]));
vector<P> p; #define eps 1e-8 s.push_back(s[0]);
vector<pair<P, int>> a; typedef Point<double> P; double ans = 0;
for (i = 0; i < (int) s.size() - 1; i++) ans += s[i].
HullIntersection(const vector<P>& ps) : N(sz(ps)), p(ps) struct Line { ,→cross(s[i + 1]);
,→{ P P1, P2; return ans / 2;
p.insert(p.end(), all(ps)); // Right hand side of the ray P1 -> P2 } // hash-cpp-all = 14dcf5189b7cf618cfdb2b4d044eb425
int b = 0; explicit Line(P a = P(), P b = P()) : P1(a), P2(b) {};
rep(i,1,N) if (P{p[i].y,p[i].x} < P{p[b].y, p[b].x}) b P intpo(Line y) {
,→= i; P r; 7.4 Misc. Point Set Problems
rep(i,0,N) { assert(lineIntersection(P1, P2, y.P1, y.P2, r) == 1);
int f = (i + b) % N; return r; closestPair.h
a.emplace_back(p[f+1] - p[f], f); } Description: i1, i2 are the indices to the closest pair of points in the
} P dir() { point vector p after the call. The distance is returned.
} return P2 - P1; Time: O (n log n)
} "Point.h" 58 lines
int qd(P p) { bool contains(P x) { template<class It>
return (p.y < 0) ? (p.x >= 0) + 2 return (P2 - P1).cross(x - P1) < eps; bool it_less(const It& i, const It& j) { return *i < *j; }
: (p.x <= 0) * (1 + (p.y <= 0)); } template<class It>
} bool out(P x) { bool y_it_less(const It& i,const It& j) {return i->y < j->y
return !contains(x); ,→;}
MIT NULL kdTree DelaunayTriangulation FastDelaunay 20
const T INF = numeric_limits<T>::max(); DelaunayTriangulation.h
template<class It, class IIt> /* IIt = vector<It>::iterator Description: Computes the Delaunay triangulation of a set of points.
,→ */ bool on_x(const P& a, const P& b) { return a.x < b.x; } Each circumcircle contains none of the input points. If any three points
double cp_sub(IIt ya, IIt yaend, IIt xa, It &i1, It &i2) { bool on_y(const P& a, const P& b) { return a.y < b.y; } are colinear or any four are on the same circle, behavior is undefined.
typedef typename iterator_traits<It>::value_type P; Time: O n2
int n = yaend-ya, split = n/2; struct Node { "Point.h", "3dHull.h" 10 lines
if(n <= 3) { // base case P pt; // if this is a leaf, the single point in it template<class P, class F>
double a = (*xa[1]-*xa[0]).dist(), b = 1e50, c = 1e50; T x0 = INF, x1 = -INF, y0 = INF, y1 = -INF; // bounds void delaunay(vector<P>& ps, F trifun) {
if(n==3) b=(*xa[2]-*xa[0]).dist(), c=(*xa[2]-*xa[1]). Node *first = 0, *second = 0; if (sz(ps) == 3) { int d = (ps[0].cross(ps[1], ps[2]) <
,→dist(); ,→0);
if(a <= b) { i1 = xa[1]; T distance(const P& p) { // min squared distance to a trifun(0,1+d,2-d); }
if(a <= c) return i2 = xa[0], a; ,→point vector<P3> p3;
else return i2 = xa[2], c; T x = (p.x < x0 ? x0 : p.x > x1 ? x1 : p.x); trav(p, ps) p3.emplace_back(p.x, p.y, p.dist2());
} else { i1 = xa[2]; T y = (p.y < y0 ? y0 : p.y > y1 ? y1 : p.y); if (sz(ps) > 3) trav(t, hull3d(p3)) if ((p3[t.b]-p3[t.a])
if(b <= c) return i2 = xa[0], b; return (P(x,y) - p).dist2(); ,→.
else return i2 = xa[1], c; } cross(p3[t.c]-p3[t.a]).dot(P3(0,0,1)) < 0)
} } trifun(t.a, t.c, t.b);
vector<It> ly, ry, stripy; Node(vector<P>&& vp) : pt(vp[0]) { } // hash-cpp-all = d173fc69317d23d87be99189086af6d2
P splitp = *xa[split]; for (P p : vp) {
double splitx = splitp.x; x0 = min(x0, p.x); x1 = max(x1, p.x);
for(IIt i = ya; i != yaend; ++i) { // Divide y0 = min(y0, p.y); y1 = max(y1, p.y); FastDelaunay.h
if(*i != xa[split] && (**i-splitp).dist2() < 1e-12) } Description: Fast Delaunay triangulation. There must be no dupli-
return i1 = *i, i2 = xa[split], 0;// nasty special if (vp.size() > 1) { cate points. If all points are on a line, no triangles will be returned.
,→case! // split on x if the box is wider than high (not best Should work for doubles as well, though there may be precision issues
if (**i < splitp) ly.push_back(*i); ,→ heuristic...) in ’circ’. Returns triangles in order {t[0][0], t[0][1], t[0][2], t[1][0], . . . },
else ry.push_back(*i); sort(all(vp), x1 - x0 >= y1 - y0 ? on_x : on_y); all counter-clockwise.
} // assert((signed)lefty.size() == split) // divide by taking half the array for each child ( Time: O (n log n)
It j1, j2; // Conquer ,→not "Point.h" 90 lines
double a = cp_sub(ly.begin(), ly.end(), xa, i1, i2); // best performance with many duplicates in the typedef Point<ll> P;
double b = cp_sub(ry.begin(), ry.end(), xa+split, j1, j2) ,→middle) typedef struct Quad* Q;
,→; int half = sz(vp)/2; typedef __int128_t lll; // (can be ll if coords are < 2e4)
if(b < a) a = b, i1 = j1, i2 = j2; first = new Node({vp.begin(), vp.begin() + half}); P arb(LLONG_MAX,LLONG_MAX); // not equal to any other point
double a2 = a*a; second = new Node({vp.begin() + half, vp.end()});
for(IIt i = ya; i != yaend; ++i) { // Create strip (y- } struct Quad {
,→sorted) } bool mark; Q o, rot; P p;
double x = (*i)->x; }; P F() { return r()->p; }
if(x >= splitx-a && x <= splitx+a) stripy.push_back(*i) Q r() { return rot->rot; }
,→; struct KDTree { Q prev() { return rot->o->rot; }
} Node* root; Q next() { return rot->r()->o->rot; }
for(IIt i = stripy.begin(); i != stripy.end(); ++i) { KDTree(const vector<P>& vp) : root(new Node({all(vp)})) };
const P &p1 = **i; ,→{}
for(IIt j = i+1; j != stripy.end(); ++j) { bool circ(P p, P a, P b, P c) { // is p in the circumcircle
const P &p2 = **j; pair<T, P> search(Node *node, const P& p) { ,→?
if(p2.y-p1.y > a) break; if (!node->first) { lll p2 = p.dist2(), A = a.dist2()-p2,
double d2 = (p2-p1).dist2(); // uncomment if we should not find the point itself: B = b.dist2()-p2, C = c.dist2()-p2;
if(d2 < a2) i1 = *i, i2 = *j, a2 = d2; // if (p == node->pt) return {INF, P()}; return p.cross(a,b)*C + p.cross(b,c)*A + p.cross(c,a)*B >
} } return make_pair((p - node->pt).dist2(), node->pt); ,→ 0;
return sqrt(a2); } }
} Q makeEdge(P orig, P dest) {
Node *f = node->first, *s = node->second; Q q0 = new Quad{0,0,0,orig}, q1 = new Quad{0,0,0,arb},
template<class It> // It is random access iterators of T bfirst = f->distance(p), bsec = s->distance(p); q2 = new Quad{0,0,0,dest}, q3 = new Quad{0,0,0,arb};
,→point<T> if (bfirst > bsec) swap(bsec, bfirst), swap(f, s); q0->o = q0; q2->o = q2; // 0-0, 2-2
double closestpair(It begin, It end, It &i1, It &i2 ) { q1->o = q3; q3->o = q1; // 1-3, 3-1
vector<It> xa, ya; // search closest side first, other side if needed q0->rot = q1; q1->rot = q2;
assert(end-begin >= 2); auto best = search(f, p); q2->rot = q3; q3->rot = q0;
for (It i = begin; i != end; ++i) if (bsec < best.first) return q0;
xa.push_back(i), ya.push_back(i); best = min(best, search(s, p)); }
sort(xa.begin(), xa.end(), it_less<It>); return best; void splice(Q a, Q b) {
sort(ya.begin(), ya.end(), y_it_less<It>); } swap(a->o->rot->o, b->o->rot->o); swap(a->o, b->o);
return cp_sub(ya.begin(), ya.end(), xa.begin(), i1, i2); }
} // hash-cpp-all = 42735b8e08701a3b73504ac0690e31df // find nearest point to a point, and its squared Q connect(Q a, Q b) {
,→distance Q q = makeEdge(a->F(), b->p);
// (requires an arbitrary operator< for Point) splice(q, a->next());
kdTree.h pair<T, P> nearest(const P& p) { splice(q->r(), b);
Description: KD-tree (2d, can be extended to 3d) return search(root, p); return q;
"Point.h" 63 lines } }
typedef long long T; }; // hash-cpp-all = bac5b0409b201c3b040301344a40dc31
typedef Point<T> P; pair<Q,Q> rec(const vector<P>& s) {
MIT NULL PolyhedronVolume Point3D 3dHull sphericalDistance KMP 21
if (sz(s) <= 3) { Point3D.h q = q * -1;
Q a = makeEdge(s[0], s[1]), b = makeEdge(s[1], s.back() Description: Class to handle points in 3D space. T can be e.g. double F f{q, i, j, k};
,→); or long long. 32 lines
E(a,b).ins(k); E(a,c).ins(j); E(b,c).ins(i);
if (sz(s) == 2) return { a, a->r() }; FS.push_back(f);
splice(a->r(), b); template<class T> struct Point3D { };
auto side = s[0].cross(s[1], s[2]); typedef Point3D P; rep(i,0,4) rep(j,i+1,4) rep(k,j+1,4)
Q c = side ? connect(b, a) : 0; typedef const P& R; mf(i, j, k, 6 - i - j - k);
return {side < 0 ? c->r() : a, side < 0 ? c : b->r() }; T x, y, z;
} explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) rep(i,4,sz(A)) {
,→{} rep(j,0,sz(FS)) {
#define H(e) e->F(), e->p bool operator<(R p) const { F f = FS[j];
#define valid(e) (e->F().cross(H(base)) > 0) return tie(x, y, z) < tie(p.x, p.y, p.z); } if(f.q.dot(A[i]) > f.q.dot(A[f.a])) {
Q A, B, ra, rb; bool operator==(R p) const { E(a,b).rem(f.c);
int half = (sz(s) + 1) / 2; return tie(x, y, z) == tie(p.x, p.y, p.z); } E(a,c).rem(f.b);
tie(ra, A) = rec({s.begin(), s.begin() + half}); P operator+(R p) const { return P(x+p.x, y+p.y, z+p.z); } E(b,c).rem(f.a);
tie(B, rb) = rec({s.begin() + half, s.end()}); P operator-(R p) const { return P(x-p.x, y-p.y, z-p.z); } swap(FS[j--], FS.back());
while ((B->p.cross(H(A)) < 0 && (A = A->next())) || P operator*(T d) const { return P(x*d, y*d, z*d); } FS.pop_back();
(A->p.cross(H(B)) > 0 && (B = B->r()->o))); P operator/(T d) const { return P(x/d, y/d, z/d); } }
Q base = connect(B->r(), A); T dot(R p) const { return x*p.x + y*p.y + z*p.z; } }
if (A->p == ra->p) ra = base->r(); P cross(R p) const { int nw = sz(FS);
if (B->p == rb->p) rb = base; return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x); rep(j,0,nw) {
} F f = FS[j];
#define DEL(e, init, dir) Q e = init->dir; if (valid(e)) \ T dist2() const { return x*x + y*y + z*z; } #define C(a, b, c) if (E(a,b).cnt() != 2) mf(f.a, f.b, i, f
while (circ(e->dir->F(), H(base), e->F())) { \ double dist() const { return sqrt((double)dist2()); } ,→.c);
Q t = e->dir; \ //Azimuthal angle (longitude) to x-axis in interval [-pi, C(a, b, c); C(a, c, b); C(b, c, a);
splice(e, e->prev()); \ ,→ pi] }
splice(e->r(), e->r()->prev()); \ double phi() const { return atan2(y, x); } }
e = t; \ //Zenith angle (latitude) to the z-axis in interval [0, trav(it, FS) if ((A[it.b] - A[it.a]).cross(
} ,→pi] A[it.c] - A[it.a]).dot(it.q) <= 0) swap(it.c, it.b);
for (;;) { double theta() const { return atan2(sqrt(x*x+y*y),z); } return FS;
DEL(LC, base->r(), o); DEL(RC, base, prev()); P unit() const { return *this/(T)dist(); } //makes dist() }; // hash-cpp-all = c172e9f2cb6b44ceca0c416fee81f1dc
if (!valid(LC) && !valid(RC)) break; ,→=1
if (!valid(LC) || (valid(RC) && circ(H(RC), H(LC)))) //returns unit vector normal to *this and p
base = connect(RC, base->r()); P normal(P p) const { return cross(p).unit(); } sphericalDistance.h
else //returns point rotated ’angle’ radians ccw around axis Description: Returns the shortest distance on the sphere with radius
base = connect(base->r(), LC->r()); P rotate(double angle, P axis) const { radius between the points with azimuthal angles (longitude) f1 (φ1 ) and
} double s = sin(angle), c = cos(angle); P u = axis.unit f2 (φ2 ) from x axis and zenith angles (latitude) t1 (θ1 ) and t2 (θ2 ) from
return { ra, rb }; ,→(); z axis. All angles measured in radians. The algorithm starts by con-
} return u*dot(u)*(1-c) + (*this)*c - cross(u)*s; verting the spherical coordinates to cartesian coordinates so if that is
} what you have you can use only the two last rows. dx*radius is then
vector<P> triangulate(vector<P> pts) { }; // hash-cpp-all = 8058aeda36daf3cba079c7bb0b43dcea the difference between the two points in the x direction and d*radius is
sort(all(pts)); assert(unique(all(pts)) == pts.end()); the total distance between the points. 8 lines
if (sz(pts) < 2) return {}; double sphericalDistance(double f1, double t1,
Q e = rec(pts).first; 3dHull.h double f2, double t2, double radius) {
vector<Q> q = {e}; Description: Computes all faces of the 3-dimension hull of a point
set. *No four points must be coplanar*, or else random results will be double dx = sin(t2)*cos(f2) - sin(t1)*cos(f1);
int qi = 0; double dy = sin(t2)*sin(f2) - sin(t1)*sin(f1);
while (e->o->F().cross(e->F(), e->p) < 0) e = e->o; returned. All faces will point outwards.
Time: O n2 double dz = cos(t2) - cos(t1);
#define ADD { Q c = e; do { c->mark = 1; pts.push_back(c->p double d = sqrt(dx*dx + dy*dy + dz*dz);
,→); \ "Point3D.h" 49 lines
return radius*2*asin(d/2);
q.push_back(c->r()); c = c->next(); } while (c != e); } typedef Point3D<double> P3; } // hash-cpp-all = 611f0797307c583c66413c2dd5b3ba28
ADD; pts.clear();
while (qi < sz(q)) if (!(e = q[qi++])->mark) ADD; struct PR {
return pts; void ins(int x) { (a == -1 ? a : b) = x; }
} // hash-cpp-all = bfb5deb6acc9a794f45978d08f765fbe void rem(int x) { (a == x ? a : b) = -1; } Strings (8)
int cnt() { return (a != -1) + (b != -1); }
int a, b; KMP.h
7.5 3D }; Description: pi[x] computes the length of the longest prefix of s that
ends at x, other than s[0...x] itself (abacaba -> 0010123). Can be used
PolyhedronVolume.h struct F { P3 q; int a, b, c; }; to find all occurrences of a string.
Description: Magic formula for the volume of a polyhedron. Faces
Time: O (n)
should point outwards. 6 lines vector<F> hull3d(const vector<P3>& A) { 16 lines

assert(sz(A) >= 4); vi pi(const string& s) {


template<class V, class L>
vector<vector<PR>> E(sz(A), vector<PR>(sz(A), {-1, -1})); vi p(sz(s));
double signed_poly_volume(const V& p, const L& trilist) {
#define E(x,y) E[f.x][f.y] rep(i,1,sz(s)) {
double v = 0;
vector<F> FS; int g = p[i-1];
trav(i, trilist) v += p[i.a].cross(p[i.b]).dot(p[i.c]);
auto mf = [&](int i, int j, int k, int l) { while (g && s[i] != s[g]) g = p[g-1];
return v / 6;
P3 q = (A[j] - A[i]).cross((A[k] - A[i])); p[i] = g + (s[i] == s[g]);
} // hash-cpp-all = 1ec4d393ab307cedc3866534eaa83a0e
if (q.dot(A[l]) > q.dot(A[i])) }
MIT NULL extended-KMP Manacher MinRotation string-sa+lcp string-SAM string-dc3 22
return p; MinRotation.h else {
} Description: Finds the lexicographically smallest rotation of a string. q=son[p][k];
Usage: rotate(v.begin(), v.begin()+min rotation(v), if (l[p]+1==l[q]) par[np]=q;
vi match(const string& s, const string& pat) { v.end()); else {
vi p = pi(pat + ’\0’ + s), res; Time: O (N ) 8 lines
nq=++len;
rep(i,sz(p)-sz(s),sz(p)) l[nq]=l[p]+1;
if (p[i] == sz(pat)) res.push_back(i - 2 * sz(pat)); int min_rotation(string s) { s[nq]=0;
return res; int a=0, N=sz(s); s += s; memset(son[nq], son[q], sizeof son[q]);
} // hash-cpp-all = d4375c5f06b664278b2df96136a588d9 rep(b,0,N) rep(i,0,N) { par[nq]=par[q];
if (a+i == b || s[a+i] < s[b+i]) {b += max(0, i-1); par[q]=nq;
,→break;} par[np]=nq;
extended-KMP.h if (s[a+i] > s[b+i]) { a = b; break; } while (p&&son[p][k]==q) son[p][k]=nq,p=par[p];
Description: extended KMP S[i] stores the maximum common prefix } }
between s[i:] and t; T[i] stores the maximum common prefix between return a; }
t[i:] and t for i>0; 33 lines
} // hash-cpp-all = 358164768a20176868eba20757681e19 last[ss]=np;
int S[N], T[N]; }
string-sa+lcp.cpp int main()
void extKMP(const string&s, const string &t) { Description: SA + LCP {
int m = t.size(); Usage: da(str, sa, strlen(str)+1, 256); read(n);
T[0] = 0; calheight(str, sa, strlen(str)); last[1]=init=len=1;
31 lines
int maT = 0; for (i=2;i<=n;i++)
for (int i = 1; i < m; i++) { int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; {
if (maT + T[maT] >= i) { int cmp(int *r,int a,int b,int l) { // hash-cpp-1 read(fa[i]);
T[i] = min(T[i - maT], maT + T[maT] - i); return r[a]==r[b]&&r[a+l]==r[b+l]; for (k=getchar();k<=32;k=getchar());
}else { } ins(last[fa[i]],i,k-’a’);
T[i] = 0; void da(int *r,int *sa,int n,int m) { }
} int i,j,p,*x=wa,*y=wb,*t; } // hash-cpp-all = 6de1ae4723820c6fbc161c9e51574990
while (T[i] + i < m && t[T[i]] == t[T[i] + i]) for(i=0;i<m;i++) ws[i]=0;
T[i]++; for(i=0;i<n;i++) ws[x[i]=r[i]]++;
if (i + T[i] > maT + T[maT]) for(i=1;i<m;i++) ws[i]+=ws[i-1];
for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
maT = i;
for(j=1,p=1;p<n;j*=2,m=p){ string-dc3.cpp
} Description: Linear-time SA+LCP+Tree
int maS = 0; for(p=0,i=n-j;i<n;i++) y[p++]=i; 108 lines

int n = s.size(); for(i=0;i<n;i++) const int N=1000010;


for (int i = 0; i < n; i++) { if(sa[i]>=j) y[p++]=sa[i]-j; char s[N];
if (maS + S[maS] >= i) { for(i=0;i<n;i++) wv[i]=x[y[i]]; int *h;
S[i] = min(T[i - maS], maS + S[maS] - i); for(i=0;i<m;i++) ws[i]=0;
}else { for(i=0;i<n;i++) ws[wv[i]]++; namespace SuffixArray {
S[i] = 0; for(i=1;i<m;i++) ws[i]+=ws[i-1];
} for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; const int N=1000010;
while (S[i] < m && i + S[i] < n && t[S[i]] == s[S[i] + for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
,→i]) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; int sa[N],rk[N],ht[N];
S[i]++; } bool t[N<<1];
if (i + S[i] > maS + S[maS]) } // hash-cpp-1 = ce2b3946ed8dab557ac57271351047a5
maS = i; //height[i]: lcp(sa[i],sa[i-1]) bool islms(const int i,const bool *t) { // hash-cpp-1
int rank[maxn],height[maxn]; return i>0&&t[i]&&!t[i - 1];
} void calheight(int *r,int *sa,int n) { // hash-cpp-2 } // hash-cpp-1 = 5ca6c1c830ec37aed73de79822fb6c8e
} int i,j,k=0;
// hash-cpp-all = 40cf01c6dd1669aaac6106a10af35b35 for(i=1;i<=n;i++) rank[sa[i]]=i; template<class T>
for(i=0;i<n;height[rank[i++]]=k) inline void sort(T s,int *sa,const int len,const int sz,
for(k?k--:0,j=sa[rank[i]-1]; r[i+k]==r[j+k]; k++); ,→const int sigma,
Manacher.h } // hash-cpp-2 = 29b5645cc1aca9a59ff90adec1d537e5 bool *t,int *b,int *cb,int *p) { // hash-cpp-2
Description: For each position in a string, computes p[0][i] = half memset(b,0,sizeof(int)*sigma);
length of longest even palindrome around pos i, p[1][i] = longest odd memset(sa,-1,sizeof(int)*len);
(half rounded down).
string-SAM.cpp rep(i,0,len) b[(int)s[i]]++;
Description: Suffix Automaton (SAM)
Time: O (N ) 11 lines
37 lines cb[0]=b[0];
int n,i,init,L,len,ll,q,h,ch,p,last[1700000],n1[1700000],du rep(i,1,sigma) cb[i]=cb[i-1]+b[i];
void manacher(const string& s) {
,→[1700000],s[1700000],fa[800001],l[1700000],son per(i,0,sz) sa[--cb[(int)s[p[i]]]]=p[i];
int n = sz(s);
,→[1700000][3],par[1700000]; rep(i,1,sigma) cb[i]=cb[i-1]+b[i-1];
vi p[2] = {vi(n+1), vi(n)};
char S[8000001],k; rep(i,0,len) if (sa[i]>0&&!t[sa[i]-1]) sa[cb[(int)s[sa[i
rep(z,0,2) for (int i=0,l=0,r=0; i < n; i++) {
long long ans,sum[1600001]; ,→]-1]]++]=sa[i]-1;
int t = r-i+!z;
void ins(int p,int ss,int k) cb[0]=b[0];
if (i<r) p[z][i] = min(t, p[z][l+t]);
{ rep(i,1,sigma) cb[i]=cb[i-1]+b[i];
int L = i-p[z][i], R = i+p[z][i]-!z;
int np=++len,q,nq; per(i,0,len) if (sa[i]>0&&t[sa[i]-1]) sa[--cb[(int)s[sa[i
while (L>=1 && R+1<n && s[L-1] == s[R+1])
l[np]=l[p]+1; ,→]-1]]]=sa[i]-1;
p[z][i]++, L--, R++;
s[np]=1; } // hash-cpp-2 = 88f5a486e24125b363a4fdb671376629
if (R>r) l=L, r=R;
while (p&&!son[p][k]) son[p][k]=np,p=par[p];
}} // hash-cpp-all = d9436881723eb8d866ac15aa011523db
if (!p) par[np]=1; template<class T>
MIT NULL SuffixTree Hashing 23
inline void sais(T s,int *sa,const int len,bool *t,int *b, } static pii LCS(string s, string t) {
,→int *b1, int t=0,rt=stk[0]; SuffixTree st(s + (char)(’z’ + 1) + t + (char)(’z’ + 2)
const int sigma) { // hash-cpp-3 int *q=stk; ,→);
int p=-1,*cb=b+sigma; q[t++]=rt; st.lcs(0, sz(s), sz(s) + 1 + sz(t), 0);
t[len-1]=1; rep(i,0,t) { return st.best;
per(i,0,len-1) t[i]=s[i]<s[i+1]||(s[i]==s[i+1]&&t[i+1]); int u=q[i]; sz[u]=1; }
int sz=0,cnt=0; if (l[u]) q[t++]=l[u],par[l[u]]=u; }; // hash-cpp-all = aae0b8bb2efccb834b9a439b63d92f53
rep(i,1,len) if (t[i]&&!t[i-1]) b1[sz++]=i; if (r[u]) q[t++]=r[u],par[r[u]]=u;
sort(s,sa,len,sz,sigma,t,b,cb,b1); }
sz=0; } // hash-cpp-6 = 496cf09518bc84e0fc8000c0f7adf03d
rep(i,0,len) if (islms(sa[i],t)) sa[sz++]=sa[i];
rep(i,sz,len) sa[i]=-1;
rep(i,0,sz) { SuffixTree.h
int x=sa[i]; Description: Ukkonen’s algorithm for online suffix tree construction.
Hashing.h
rep(j,0,len) { Description: Various self-explanatory methods for string hashing.
45 lines
Each node contains indices [l, r) into the string, and a list of child nodes.
if (p==-1||s[x+j]!=s[p+j]||t[x+j]!=t[p+j]) { Suffixes are given by traversals of this tree, joining [l, r) substrings. The // Arithmetic mod 2ˆ64-1. 2x slower than mod 2ˆ64 and more
cnt++; p=x; root is 0 (has l = -1, r = 0), non-existent children are -1. To get a // code, but works on evil test data (e.g. Thue-Morse,
break; complete tree, append a dummy symbol – otherwise it may contain an ,→where
} else if (j>0&&(islms(x+j,t)||islms(p+j,t))) { incomplete path (still useful for substring matching, though). // ABBA... and BAAB... of length 2ˆ10 hash the same mod
break; Time: O (26N ) 50 lines ,→2ˆ64).
}
// "typedef ull H;" instead if you think test data is
} struct SuffixTree {
,→random,
sa[sz+(x>>=1)]=cnt-1; enum { N = 200010, ALPHA = 26 }; // N ∼ 2*maxlen+10
// or work mod 10ˆ9+7 if the Birthday paradox is not a
} int toi(char c) { return c - ’a’; }
,→problem.
for (int i=len-1,j=len-1;i>=sz;i--) if (sa[i]>=0) sa[j string a; // v = cur node, q = cur position
struct H {
,→--]=sa[i]; int t[N][ALPHA],l[N],r[N],p[N],s[N],v=0,q=0,m=2;
typedef uint64_t ull;
int *s1=sa+len-sz,*b2=b1+sz;
ull x; H(ull x=0) : x(x) {}
if (cnt<sz) sais(s1,sa,sz,t+len,b,b1+sz,cnt); void ukkadd(int i, int c) { suff:
#define OP(O,A,B) H operator O(H o) { ull r = x; asm \
else rep(i,0,sz) sa[s1[i]]=i; if (r[v]<=q) {
(A "addq %%rdx, %0\n adcq $0,%0" : "+a"(r) : B); return r
rep(i,0,sz) b2[i]=b1[sa[i]]; if (t[v][c]==-1) { t[v][c]=m; l[m]=i;
,→; }
sort(s,sa,len,sz,sigma,t,b,cb,b2); p[m++]=v; v=s[v]; q=r[v]; goto suff; }
OP(+,,"d"(o.x)) OP(*,"mul %1\n", "r"(o.x) : "rdx")
} // hash-cpp-3 = 06c63b43c0de339e2fbc000178dc4084 v=t[v][c]; q=l[v];
H operator-(H o) { return *this + ∼o.x; }
}
ull get() const { return x + !∼x; }
template<class T> if (q==-1 || c==toi(a[q])) q++; else {
bool operator==(H o) const { return get() == o.get(); }
inline void getHeight(T s,int n) { // hash-cpp-4 l[m+1]=i; p[m+1]=m; l[m]=l[v]; r[m]=q;
bool operator<(H o) const { return get() < o.get(); }
rep(i,1,n+1) rk[sa[i]]=i; p[m]=p[v]; t[m][c]=m+1; t[m][toi(a[q])]=v;
};
int j=0,k=0; l[v]=q; p[v]=m; t[p[m]][toi(a[l[m]])]=m;
static const H C = (ll)1e11+3; // (order ∼ 3e9; random also
for (int i=0;i<n;ht[rk[i++]]=k) v=s[p[m]]; q=l[m];
,→ ok)
for (k?k--:0,j=sa[rk[i]-1];s[i+k]==s[j+k];k++); while (q<r[m]) { v=t[v][toi(a[q])]; q+=r[v]-l[v]; }
} // hash-cpp-4 = d171edf9c242a8cdb65bbca53aab75dd if (q==r[m]) s[m]=v; else s[m]=m+2;
struct HashInterval {
q=r[v]-(q-r[m]); m+=2; goto suff;
vector<H> ha, pw;
template<class T> }
HashInterval(string& str) : ha(sz(str)+1), pw(ha) {
inline void init(T s,const int len,const int sigma) { // }
pw[0] = 1;
,→hash-cpp-5
rep(i,0,sz(str))
sais(s,sa,len,t,rk,ht,sigma); SuffixTree(string a) : a(a) {
ha[i+1] = ha[i] * C + str[i],
} // hash-cpp-5 = e90e73297525a28516de9c2d1653b256 fill(r,r+N,sz(a));
pw[i+1] = pw[i] * C;
memset(s, 0, sizeof s);
}
inline void solve(char *s,int len) { memset(t, -1, sizeof t);
H hashInterval(int a, int b) { // hash [a, b)
init(s,len+1,124); fill(t[1],t[1]+ALPHA,0);
return ha[b] - ha[a] * pw[b - a];
getHeight(s,len); s[0] = 1; l[0] = l[1] = -1; r[0] = r[1] = p[0] = p[1] =
}
} ,→ 0;
};
} // namespace SuffixArray rep(i,0,sz(a)) ukkadd(i, toi(a[i]));
}
vector<H> getHashes(string& str, int length) {
int n;
if (sz(str) < length) return {};
// example: find longest common substring (uses ALPHA =
H h = 0, pw = 1;
int stk[N],top,a[N],l[N],r[N],sz[N],par[N]; ,→28)
rep(i,0,length)
pii best;
h = h * C + str[i], pw = pw * C;
void build() { // hash-cpp-6 int lcs(int node, int i1, int i2, int olen) {
vector<H> ret = {h};
int top=0; if (l[node] <= i1 && i1 < r[node]) return 1;
rep(i,length,sz(str)) {
h=SuffixArray::ht+1; if (l[node] <= i2 && i2 < r[node]) return 2;
ret.push_back(h = h * C + str[i] - pw * str[i-length]);
rep(i,1,n) l[i]=r[i]=par[i]=0; int mask = 0, len = node ? olen + (r[node] - l[node]) :
}
rep(i,1,n) { ,→ 0;
return ret;
int k=top; rep(c,0,ALPHA) if (t[node][c] != -1)
}
while (k>0&&h[stk[k-1]]>h[i]) --k; mask |= lcs(t[node][c], i1, i2, len);
if (k) r[stk[k-1]]=i; if (mask == 3)
H hashString(string& s) { H h{}; trav(c,s) h=h*C+c; return
if (k<top) l[i]=stk[k]; best = max(best, {len, r[node] - len});
,→h; }
stk[k++]=i; return mask;
// hash-cpp-all = acb5db796db96a22e754975ae2ee96c5
top=k; }
MIT NULL AhoCorasick Karatsuba KnuthDP BumpAllocator SmallPtr BumpAllocatorSTL 24
AhoCorasick.h vector<vi> findAll(vector<string>& pat, string word) { • for (int x = m; x; ) { --x &= m; ...
Description: Aho-Corasick tree is used for multiple pattern matching. vi r = find(word);
Initialize the tree with create(patterns). find(word) returns for each vector<vi> res(sz(word));
} loops over all subset masks of m (except m itself).
position the index of the longest word that√ ends there, or -1 if none. rep(i,0,sz(word)) {
findAll( , word) finds all words (up to N N many if no duplicate pat- int ind = r[i]; • c = x&-x, r = x+c; (((rˆx) >> 2)/c) |
terns) that start at each position (shortest first). Duplicate patterns are while (ind != -1) { r is the next number after x with the same
allowed; empty patterns are not. To find the longest words that start res[i - sz(pat[ind]) + 1].push_back(ind);
at each position, reverse all input. ind = backp[ind]; number of bits set.
Time: Function create is O (26N ) where N is the sum of length of }
patterns. find is O (M ) where M is the length of the word. findAll is } •rep(b,0,K) rep(i,0,(1 << K)) if (i &
O (N M ). return res;
67 lines
} 1 << b) D[i] += D[iˆ(1 << b)];
struct AhoCorasick {
enum {alpha = 26, first = ’A’};
}; // hash-cpp-all = 716ac4cbf4109c8b0ba0795702a8bfe1 computes all sums of subsets.
struct Node { 9.4.2 Pragmas
// (nmatches is optional)
int back, next[alpha], start = -1, end = -1, nmatches = Various (9) • #pragma GCC optimize ("Ofast")will make GCC
,→ 0;
Node(int v) { memset(next, v, sizeof(next)); }
9.1 Misc. algorithms auto-vectorize for loops and optimizes floating
};
vector<Node> N; points better (assumes associativity and turns off
Karatsuba.h
vector<int> backp; Description: Faster-than-naive convolution of two sequences: c[x] = denormals).
void insert(string& s, int j) { P
a[i]b[x − i]. Uses the identity (aX + b)(cX + d) = acX 2 + bd + ((a +
assert(!s.empty());
int n = 0;
c)(b + d) − ac − bd)X. Doesn’t handle sequences of very different length • can double
#pragma GCC target ("avx,avx2")
well. See also FFT, under the Numerical chapter.
trav(c, s) { Time: O N 1.6
 performance of vectorized code, but causes crashes
int& m = N[n].next[c - first]; 1 lines

if (m == -1) { n = m = sz(N); N.emplace_back(-1); } // hash-cpp-all = d41d8cd98f00b204e9800998ecf8427e


on old machines.
else n = m;
} • #pragma GCC optimize ("trapv") kills the program on
if (N[n].end == -1) N[n].start = j; 9.2 Dynamic programming integer overflows (but is really slow).
backp.push_back(N[n].end);
N[n].end = j;
KnuthDP.h
N[n].nmatches++;
Description: When doing DP on intervals: a[i][j] = mini<k<j (a[i][k]+ BumpAllocator.h
a[k][j]) + f (i, j), where the (minimal) optimal k increases with both i Description: When you need to dynamically allocate many objects and
}
and j, one can solve intervals in increasing order of length, and search don’t care about freeing them. ”new X” otherwise has an overhead of
AhoCorasick(vector<string>& pat) {
k = p[i][j] for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This is something like 0.05us + 16 bytes per allocation.
N.emplace_back(-1); 9 lines
known as Knuth DP. Sufficient criteria for this are if f (b, c) ≤ f (a, d)
rep(i,0,sz(pat)) insert(pat[i], i); // Either globally or in a single class:
and f (a, c) + f (b, d) ≤ f (a, d) + f (b, c) for all a ≤ b ≤ c ≤ d. Consider
N[0].back = sz(N); static char buf[450 << 20];
also: LineContainer (ch. Data structures), monotone queues, ternary
N.emplace_back(0); void* operator new(size_t s) {
search.
Time: O N 2 static size_t i = sizeof buf;

queue<int> q; 1 lines
assert(s < i);
for (q.push(0); !q.empty(); q.pop()) { // hash-cpp-all = d41d8cd98f00b204e9800998ecf8427e return (void*)&buf[i -= s];
int n = q.front(), prev = N[n].back; }
rep(i,0,alpha) { void operator delete(void*) {}
int &ed = N[n].next[i], y = N[prev].next[i]; 9.3 Debugging tricks // hash-cpp-all = 745db225903de8f3cdfa051660956100
if (ed == -1) ed = y;
else {
N[ed].back = y;
• signal(SIGSEGV, [](int) { Exit(0); SmallPtr.h
(N[ed].end == -1 ? N[ed].end : backp[N[ed].start }); converts segfaults into Wrong Answers. Description: A 32-bit pointer that points into BumpAllocator memory.
,→]) "BumpAllocator.h" 10 lines
= N[y].end;
Similarly one can catch SIGABRT (assertion
template<class T> struct ptr {
N[ed].nmatches += N[y].nmatches; failures) and SIGFPE (zero divisions). unsigned ind;
q.push(ed); ptr(T* p = 0) : ind(p ? unsigned((char*)p - buf) : 0) {
}
GLIBCXX DEBUG violations generate SIGABRT
assert(ind < sizeof buf);
} (or SIGSEGV on gcc 5.4.0 apparently). }
} T& operator*() const { return *(T*)(buf + ind); }
}
vi find(string word) {
• feenableexcept(29); kills the program on T* operator->() const { return &**this; }
T& operator[](int a) const { return (&**this)[a]; }
int n = 0; NaNs (1), 0-divs (4), infinities (8) and denormals explicit operator bool() const { return ind; }
vi res; // ll count = 0; }; // hash-cpp-all = 2dd6c9773f202bd47422e255099f4829
trav(c, word) {
(16).
n = N[n].next[c - first];
res.push_back(N[n].end); 9.4 Optimization tricks BumpAllocatorSTL.h
// count += N[n].nmatches; Description: BumpAllocator for STL containers.
} 9.4.1 Bit hacks Usage: vector<vector<int, small<int>>> ed(N); 14 lines
return res; char buf[450 << 20] alignas(16);
} • x & -x is the least bit in x. size_t buf_ind = sizeof buf;
MIT NULL Unrolling SIMD Hashmap Main 25
mi one() { return _mm256_set1_epi32(-1); }
template<class T> struct small { bool all_zero(mi m) { return _mm256_testz_si256(m, m); }
typedef T value_type; bool all_one(mi m) { return _mm256_testc_si256(m, one()); }
small() {}
template<class U> small(const U&) {} ll example_filteredDotProduct(int n, short* a, short* b) {
T* allocate(size_t n) { int i = 0; ll r = 0;
buf_ind -= n * sizeof(T); mi zero = _mm256_setzero_si256(), acc = zero;
buf_ind &= 0 - alignof(T); while (i + 16 <= n) {
return (T*)(buf + buf_ind); mi va = L(a[i]), vb = L(b[i]); i += 16;
} va = _mm256_and_si256(_mm256_cmpgt_epi16(vb, va), va);
void deallocate(T*, size_t) {} mi vp = _mm256_madd_epi16(va, vb);
}; // hash-cpp-all = bb66d4225a1941b85228ee92b9779d4b acc = _mm256_add_epi64(_mm256_unpacklo_epi32(vp, zero),
_mm256_add_epi64(acc, _mm256_unpackhi_epi32(vp, zero)
,→));
Unrolling.h 6 lines }
union {ll v[4]; mi m;} u; u.m = acc; rep(i,0,4) r += u.v[
#define F {...; ++i;}
,→i];
int i = from;
for (;i<n;++i) if (a[i] < b[i]) r += a[i]*b[i]; // <-
while (i&3 && i < to) F // for alignment, if needed
,→equiv
while (i + 4 <= to) { F F F F }
return r;
while (i < to) F
} // hash-cpp-all = 551b820442570276f239d9d7e0800c65
// hash-cpp-all = 520e76d6182da81d99aa0e67b36a0b3d

Hashmap.h
SIMD.h Description: Faster/better hash maps, taken from CF 14 lines
Description: Cheat sheet of SSE/AVX intrinsics, for doing arithmetic
on several numbers at once. Can provide a constant factor improvement #include <ext/pb_ds/assoc_container.hpp>
of about 4, orthogonal to loop unrolling. Operations follow the pat- using namespace __gnu_pbds;
tern " mm(256)? name (si(128|256)|epi(8|16|32|64)|pd|ps)". Not gp_hash_table<int, int> table;
all are described here; grep for mm in /usr/lib/gcc/*/4.9/include/
for more. If AVX is unsupported, try 128-bit operations, ”emmintrin.h” struct custom_hash {
and #define SSE and MMX before including it. For aligned mem- size_t operator()(uint64_t x) const {
ory use mm malloc(size, 32) or int buf[N] alignas(32), but prefer x += 48;
loadu/storeu. x = (x ˆ (x >> 30)) * 0xbf58476d1ce4e5b9;
43 lines
x = (x ˆ (x >> 27)) * 0x94d049bb133111eb;
#pragma GCC target ("avx2") // or sse4.1 return x ˆ (x >> 31);
#include "immintrin.h" }
};
typedef __m256i mi; gp_hash_table<int, int, custom_hash> safe_table;
#define L(x) _mm256_loadu_si256((mi*)&(x)) // hash-cpp-all = e62eb2668aee2263b6d72043f3652fb2

// High-level/specific methods:
// load(u)?_si256, store(u)?_si256, setzero_si256,
9.5 Other languages
,→_mm_malloc Main.java
// blendv_(epi8|ps|pd) (z?y:x), movemask_epi8 (hibits of Description: Basic template/info for Java 14 lines
,→bytes)
// i32gather_epi32(addr, x, 4): map addr[] over 32-b parts import java.util.*;
,→of x import java.math.*;
// sad_epu8: sum of absolute differences of u8, outputs 4 import java.io.*;
,→xi64 public class Main {
// maddubs_epi16: dot product of unsigned i7’s, outputs 16 public static void main(String[] args) throws Exception {
,→xi15 BufferedReader br = new BufferedReader(new
// madd_epi16: dot product of signed i16’s, outputs 8xi32 ,→InputStreamReader(System.in));
// extractf128_si256(, i) (256->128), cvtsi128_si32 (128-> PrintStream out = System.out;
,→lo32) StringTokenizer st = new StringTokenizer(br.readLine())
// permute2f128_si256(x,x,1) swaps 128-bit lanes ,→;
// shuffle_epi32(x, 3*64+2*16+1*4+0) == x for each lane assert st.hasMoreTokens(); // enable with java -ea main
// shuffle_epi8(x, y) takes a vector instead of an imm out.println("v=" + Integer.parseInt(st.nextToken()));
ArrayList<Integer> a = new ArrayList<>();
// Methods that work with most data types (append e.g. a.add(1234); a.get(0); a.remove(a.size()-1); a.clear();
,→_epi32): }
// set1, blend (i8?x:y), add, adds (sat.), mullo, sub, and/ }
,→or,
// andnot, abs, min, max, sign(1,x), cmp(gt|eq), unpack(lo|
,→hi)

int sumi32(mi m) { union {int v[8]; mi m;} u; u.m = m;


int ret = 0; rep(i,0,8) ret += u.v[i]; return ret; }
mi zero() { return _mm256_setzero_si256(); }

You might also like