Kactl
Kactl
MIT NULL
Andrew He, Kevin Sun, Yinzhan Xu
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
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
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
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)