Uet Awk
Uet Awk
AWK
Nhà E3, 144 Xuân Thủy, quận Cầu Giấy,
Hà Nội,
Việt Nam
2023-12-07
1 Contest 1 troubleshoot.txt 52 lines
ed − bf
Pre-submit:
ax + by = e x=
2 Mathematics 1 Write a few simple test cases if sample is not enough. ad − bc
⇒
Are time limits close? If so, generate max cases. cx + dy = f af − ec
Is the memory usage fine? y=
3 Data structures 3 Could anything overflow? ad − bc
Make sure to submit the right file.
In general, given an equation Ax = b, the solution to a variable
4 Numerical 5 Wrong answer: xi is given by
Print your solution! Print debug output, as well.
Are you clearing all data structures between test cases?
det A0i
5 Number theory 8 xi =
Can your algorithm handle the whole range of input? det A
Read the full problem statement again. 0
6 Combinatorial 10 Do you handle all corner cases correctly? where Ai is A with the i’th column replaced by b.
Have you understood the problem correctly?
7 Graph 11
Any uninitialized variables?
Any overflows?
2.2 Recurrences
Confusing N and M, i and j, etc.?
Are you sure your algorithm works?
If an = c1 an−1 + · · · + ck an−k , and r1 , . . . , rk are distinct roots of
8 Geometry 17 What special cases have you not thought of? xk + c1 xk−1 + · · · + ck , there are d1 , . . . , dk s.t.
Are you sure the STL functions you use work as you think?
9 Strings 21 Add some assertions, maybe resubmit. an = d1 r1n + · · · + dk rkn .
Create some testcases to run your algorithm on.
Go through the algorithm for a simple case.
10 Various 22 Go through this list again. Non-distinct roots r become polynomial factors, e.g.
Explain your algorithm to a teammate. an = (d1 n + d2 )rn .
Ask the teammate to look at your code.
Contest (1) Go for a small walk, e.g. to the toilet.
Is your output format correct? (including whitespace) 2.3 Trigonometry
Rewrite your solution from the start or let a teammate do it.
template.cpp 14 lines sin(v + w) = sin v cos w + cos v sin w
Runtime error:
#include <bits/stdc++.h> Have you tested all corner cases locally?
using namespace std; Any uninitialized variables?
cos(v + w) = cos v cos w − sin v sin w
Are you reading or writing outside the range of any vector?
#define rep(i, a, b) for(int i = a; i < (b); ++i) Any assertions that might fail?
#define all(x) begin(x), end(x) Any possible division by 0? (mod 0 for example)
#define sz(x) (int)(x).size() Any possible infinite recursion?
typedef long long ll; tan v + tan w
Invalidated pointers or iterators? tan(v + w) =
typedef pair<int, int> pii; Are you using too much memory? 1 − tan v tan w
typedef vector<int> vi; Debug with resubmits (e.g. remapped signals, see Various). v+w v−w
sin v + sin w = 2 sin cos
int main() { Time limit exceeded: 2 2
cin.tie(0)->sync_with_stdio(0); Do you have any possible infinite loops? v+w v−w
cin.exceptions(cin.failbit); What is the complexity of your algorithm? cos v + cos w = 2 cos cos
}
2 2
Are you copying a lot of unnecessary data? (References)
How big is the input and output? (consider scanf) (V + W ) tan(v − w)/2 = (V − W ) tan(v + w)/2
Avoid vector, map. (use arrays/unordered_map)
.bashrc 3 lines What do your teammates think about your algorithm? where V, W are lengths of sides opposite angles v, w.
alias c=’g++ -Wall -Wconversion -Wfatal-errors -g -std=c++14 \
Memory limit exceeded:
-fsanitize=undefined,address’
What is the max amount of memory your algorithm should need?
a cos x + b sin x = r cos(x − φ)
xmodmap -e ’clear lock’ -e ’keycode 66=less greater’ #caps = <>
Are you clearing all data structures between test cases? a sin x + b cos x = r sin(x + φ)
.vimrc √
6 lines where r = a2 + b2 , φ = atan2(b, a).
set cin aw ai is ts=4 sw=4 tm=50 nu noeb bg=dark ru cul Mathematics (2)
sy on | im jk <esc> | im kj <esc> | no ; :
" Select region and then type :Hash to hash your selection. 2.4 Geometry
" Useful for verifying that there aren’t mistypes. 2.1 Equations
ca Hash w !cpp -dD -P -fpreprocessed \| tr -d ’[:space:]’ \ 2.4.1 Triangles
\| md5sum \| cut -c-6
√ Side lengths: a, b, c
2 −b ± b2 − 4ac a+b+c
hash.sh ax + bx + c = 0 ⇒ x = Semiperimeter: p =
3 lines 2a 2
p
# Hashes a file, ignoring all whitespace and comments. Use for Area: A = p(p − a)(p − b)(p − c)
# verifying that code was correctly typed.
cpp -dD -P -fpreprocessed | tr -d ’[:space:]’| md5sum |cut -c-6 abc
The extremum is given by x = −b/2a. Circumradius: R =
4A
KTH template .bashrc .vimrc hash troubleshoot 2
A Integration by parts: 2.8.1 Discrete distributions
Inradius: r =
p
Binomial distribution
Z b b
Length √of median (divides triangle into two equal-area triangles):
Z
ma = 21 2b2 + 2c2 − a2 f (x)g(x)dx = [F (x)g(x)]ba − F (x)g 0 (x)dx
a a
Length The number of successes in n independent yes/no experiments,
v of "bisector (divides angles in two):
u 2 # each which yields success with probability p is
2.6 Sums
u a Bin(n, p), n = 1, 2, . . . , 0 ≤ p ≤ 1.
sa = tbc 1 −
b+c
cb+1 − ca
!
sin α sin β sin γ 1 ca + ca+1 + · · · + cb = , c 6= 1 p(k) =
n k
p (1 − p)n−k
Law of sines: = = = c−1 k
a b c 2R
Law of cosines: a2 = b2 + c2 − 2bc cos α
α+β n(n + 1) µ = np, σ 2 = np(1 − p)
tan 1 + 2 + 3 + ··· + n =
a+b 2 2 Bin(n, p) is approximately Po(np) for small p.
Law of tangents: = n(2n + 1)(n + 1)
a−b α−β 2 2 2 2
tan 1 + 2 + 3 + ··· + n =
2 6 First success distribution
3 3 3 3 n2 (n + 1)2
2.4.2 Quadrilaterals 1 + 2 + 3 + ··· + n =
4 The number of trials needed to get the first success in
With side lengths a, b, c, d, diagonals e, f , diagonals angle θ, area 4 4 4 4 n(n + 1)(2n + 1)(3n2 + 3n − 1) independent yes/no experiments, each wich yields success with
1 + 2 + 3 + ··· + n = probability p is Fs(p), 0 ≤ p ≤ 1.
A and magic flux F = b2 + d2 − a2 − c2 : 30
p(k) = p(1 − p)k−1 , k = 1, 2, . . .
p
4A = 2ef · sin θ = F tan θ = 4e2 f 2 − F 2 1 2 1−p
µ= ,σ =
2.7 Series p p2
◦
For cyclic quadrilateralspthe sum of opposite angles is 180 , x2 x3 Poisson distribution
ex = 1 + x + + + . . . , (−∞ < x < ∞)
ef = ac + bd, and A = (p − a)(p − b)(p − c)(p − d). 2! 3!
The number of events occurring in a fixed period of time t if these
2.4.3 Spherical coordinates x2 x3 x4 events occur with a known average rate κ and independently of
ln(1 + x) = x − + − + . . . , (−1 < x ≤ 1)
2 3 4 the time since the last event is Po(λ), λ = tκ.
z √ x x2 2x3 5x4 λk
1+x=1+ − + − + . . . , (−1 ≤ x ≤ 1) p(k) = e−λ
r 2 8 32 128 k!
, k = 0, 1, 2, . . .
y x3 x5 x7
sin x = x − + − + . . . , (−∞ < x < ∞) µ = λ, σ 2 = λ
3! 5! 7!
x x2 x4 x6 2.8.2 Continuous distributions
cos x = 1 − + − + . . . , (−∞ < x < ∞)
2! 4! 6! Uniform distribution
p
x = r sin θ cos φ r = xp 2 + y2 + z2
y = r sin θ sin φ θ = acos(z/ x2 + y 2 + z 2 ) 2.8 Probability theory If the probability density function is constant between a and b
z = r cos θ φ = atan2(y, x) and 0 elsewhere it is U(a, b), a < b.
Let X be a discrete random variable with probability pX (x) of
1
assuming theP value x. It will then have an expected value (mean) b−a
a<x<b
f (x) =
2.5 Derivatives/Integrals µ = E(X) = x xpX (x) and variance 0 otherwise
σ 2 = V (X) = E(X 2 ) − (E(X))2 = x (x − E(X))2 pX (x) where σ
P
is the standard deviation. If X is instead continuous it will have a+b 2 (b − a)2
µ= ,σ =
d 1 d 1 a probability density function fX (x) and the sums above will 2 12
arcsin x = √ arccos x = − √
dx 1 − x2 dx 1 − x2 instead be integrals with pX (x) replaced by fX (x). Exponential distribution
d d 1 Expectation is linear:
tan x = 1 + tan2 x arctan x = The time between events in a Poisson process is
dx dx 1 + x2
Z
ln | cos ax|
Z
sin ax − ax cos ax E(aX + bY ) = aE(X) + bE(Y ) Exp(λ), λ > 0.
tan ax = − λe−λx x ≥ 0
x sin ax =
a a2 f (x) =
Z √ Z ax For independent X and Y , 0 x<0
2 π e
e−x = erf(x) xeax dx = 2 (ax − 1) 1 2 1
2 a V (aX + bY ) = a2 V (X) + b2 V (Y ). µ= ,σ = 2
λ λ
KTH OrderStatisticTree HashMap SegmentTreeBeat 3
Normal distribution using Tree = tree<T, null_type, less<T>, rb_tree_tag, void down(int id, int l, int r){
tree_order_statistics_node_update>; int t = lazy[id];
lazy[id] = 0;
Most real random values with mean µ and variance σ 2 are well void example() {
int mid = (l + r) / 2;
st[id * 2] += t * (mid - l + 1);
described by N (µ, σ 2 ), σ > 0. Tree<int> t, t2; t.insert(8); st[id * 2 + 1] += t * (r - mid);
auto it = t.insert(10).first; lazy[id * 2] += t;
(x−µ)2 assert(it == t.lower_bound(9)); lazy[id * 2 + 1] += t;
1 − _max[id * 2] += t;
f (x) = √ e 2σ2 assert(t.order_of_key(10) == 1);
2πσ 2 assert(t.order_of_key(11) == 2); _max[id * 2 + 1] += t;
_min[id * 2] += t;
assert(*t.find_by_order(0) == 8); _min[id * 2 + 1] += t;
If X1 ∼ N (µ1 , σ12 ) and X2 ∼ N (µ2 , σ22 ) then t.join(t2); // assuming T < T2 or T > T2, merge t2 into t if(_semax[id * 2] != -oo) _semax[id * 2] += t;
} if(_semax[id * 2 + 1] != -oo) _semax[id * 2 + 1] += t;
if(_semin[id * 2] != oo) _semin[id * 2] += t;
aX1 + bX2 + c ∼ N (µ1 + µ2 + c, a2 σ12 + b2 σ22 ) if(_semin[id * 2 + 1] != oo) _semin[id * 2 + 1] += t;
HashMap.h int val = _max[id];
Description: Hash map with mostly the same API as unordered map, but if(_max[id * 2] > val){
∼3x faster. Uses 1.5x memory. Initial capacity must be a power of 2 (if st[id * 2] -= cntmax[id * 2] * (_max[id * 2] - val);
2.9 Markov chains provided). d77092, 7 lines
_max[id * 2] = val;
if(l == mid) _min[id * 2] = val;
A Markov chain is a discrete random process with the property #include <bits/extc++.h> else{
// To use most b i t s rather than j u s t the lowest ones : if(_min[id * 2] > val) _min[id * 2] = val;
that the next state depends only on the current state. Let struct chash { // large odd number for C else if(_semin[id * 2] > val) _semin[id * 2] = val;
const uint64_t C = ll(4e18 * acos(0)) | 71; }
X1 , X2 , . . . be a sequence of random variables generated by the }
ll operator()(ll x) const { return __builtin_bswap64(x*C); }
Markov process. Then there is a transition matrix P = (pij ), if(_max[id * 2 + 1] > val){
}; st[id * 2 + 1] -= cntmax[id * 2 + 1] * (_max[id * 2 + 1] - val);
with pij = Pr(Xn = i|Xn−1 = j), and p(n) = Pn p(0) is the __gnu_pbds::gp_hash_table<ll,int,chash> h({},{},{},{},{1<<16}); _max[id * 2 + 1] = val;
(n) if(mid + 1 == r) _min[id * 2 + 1] = val;
probability distribution for Xn (i.e., pi = Pr(Xn = i)), where else{
(0)
p is the initial distribution. SegmentTreeBeat.h if(_min[id * 2 + 1] > val) _min[id * 2 + 1] = val;
Description: Zero-indexed max-tree. Bounds are inclusive to the left and else if(_semin[id * 2 + 1] > val) _semin[id * 2 + 1] = val;
exclusive to the right. Can be changed by modifying T, f and unit. }
π is a stationary distribution if π = πP. If the Markov chain is Time: O (log N ) }
0f4bdb, 19 lines
irreducible (it is possible to get to any state from any state), then struct SegtreeBeats{
val = _min[id];
if(_min[id * 2] < val){
πi = E(T1 i ) where E(Ti ) is the expected time between two visits in int _min[4 * maxN], _semin[4 * maxN], _max[4 * maxN], _semax[4 * maxN];
st[id * 2] += cntmin[id * 2] * (val - _min[id * 2]);
int cntmin[4 * maxN], cntmax[4 * maxN], st[4 * maxN], lazy[4 * maxN];
state i. πj /πi is the expected number of visits in state j between _min[id * 2] = val;
void reset(){
if(l == mid) _max[id * 2] = val;
two visits in state i. memset(st, 0, sizeof st);
else{
memset(lazy, 0, sizeof lazy);
if(_max[id * 2] < val) _max[id * 2] = val;
memset(_min, 0, sizeof _min);
For a connected, undirected and non-bipartite graph, where the else if(_semax[id * 2] < val) _semax[id * 2] = val;
memset(_max, 0, sizeof _max);
}
transition probability is uniform among all neighbors, πi is memset(_semin, 0, sizeof _semin);
}
memset(_semax, 0, sizeof _semax);
proportional to node i’s degree. if(_min[id * 2 + 1] < val){
memset(cntmin, 0, sizeof cntmin);
st[id * 2 + 1] += cntmin[id * 2 + 1] * (val - _min[id * 2 + 1]);
memset(cntmax, 0, sizeof cntmax);
_min[id * 2 + 1] = val;
A Markov chain is ergodic if the asymptotic distribution is }
if(mid + 1 == r) _max[id * 2 + 1] = val;
void combine(int id){
independent of the initial distribution. A finite Markov chain is else{
_max[id] = max(_max[id * 2], _max[id * 2 + 1]);
if(_max[id * 2 + 1] < val) _max[id * 2 + 1] = val;
ergodic iff it is irreducible and aperiodic (i.e., the gcd of cycle int tmp = max(_semax[id * 2], _semax[id * 2 + 1]);
else if(_semax[id * 2 + 1] < val) _semax[id * 2 + 1] = val;
if(_max[id * 2] > _max[id * 2 + 1]){
}
lengths is 1). limk→∞ Pk = 1π. _semax[id] = max(tmp, _max[id * 2 + 1]);
}
cntmax[id] = cntmax[id * 2];
}
A Markov chain is an A-chain if the states can be partitioned }
void build(int id, int l, int r){
else if(_max[id * 2] < _max[id * 2 + 1]){
into two sets A and G, such that all states in A are absorbing if(l == r){
_semax[id] = max(tmp, _max[id * 2]);
_max[id] = _min[id] = st[id] = a[l];
cntmax[id] = cntmax[id * 2 + 1];
(pii = 1), and all states in G leads to an absorbing state in A. }
_semax[id] = -oo;
_semin[id] = oo;
The probability for absorption in state i ∈ A, when the initial else{
cntmax[id] = cntmin[id] = 1;
P _semax[id] = tmp;
state is j, is aij = pij + k∈G aik pkj . The expected return;
P time until cntmax[id] = cntmax[id * 2] + cntmax[id * 2 + 1];
}
absorption, when the initial state is i, is ti = 1 + k∈G pki tk . }
int mid = (l + r) / 2;
_min[id] = min(_min[id * 2], _min[id * 2 + 1]);
build(id * 2, l, mid);
tmp = min(_semin[id * 2], _semin[id * 2 + 1]);
build(id * 2 + 1, mid + 1, r);
if(_min[id * 2] < _min[id * 2 + 1]){
combine(id);
_semin[id] = min(tmp, _min[id * 2 + 1]);
}
Data structures (3) }
cntmin[id] = cntmin[id * 2];
void upd_chmax(int id, int l, int r, int u, int v, int val){
if(l > v || r < u || _min[id] >= val) return;
else if(_min[id * 2] > _min[id * 2 + 1]){
OrderStatisticTree.h _semin[id] = min(tmp, _min[id * 2]);
if(l >= u && r <= v && _semin[id] > val){
Description: A set (not multiset!) with support for finding the n’th ele- st[id] += cntmin[id] * (val - _min[id]);
cntmin[id] = cntmin[id * 2 + 1];
ment, and finding the index of an element. To get a map, change null type. _min[id] = val;
}
if(l == r) _max[id] = val;
Time: O (log N ) else{
782797, 16 lines else{
_semin[id] = tmp;
#include <bits/extc++.h> if(_max[id] < val) _max[id] = val;
cntmin[id] = cntmin[id * 2] + cntmin[id * 2 + 1];
else if(_semax[id] < val) _semax[id] = val;
using namespace __gnu_pbds; }
}
st[id] = st[id * 2] + st[id * 2 + 1];
return;
template<class T> }
}
KTH LineContainer Treap SegmentTree SegmentTreeLazy CountingLargePrime DynamicWaveletTree 4
down(id, l, r);
if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); CountingLargePrime.h
int mid = (l + r) / 2;
while ((y = x) != begin() && (--x)->p >= y->p) Description: Count the number of prime numbers up to N
upd_chmax(id * 2, l, mid, u, v, val); isect(x, erase(y)); Time: For a single run in O (sqrt(N )). e62fac, 22 lines
upd_chmax(id * 2 + 1, mid + 1, r, u, v, val); }
combine(id); ll query(ll x) {
} assert(!empty()); ll piSieve(const ll n){
void upd_chmin(int id, int l, int r, int u, int v, int val){ if (n <= 1) return 0LL;
auto l = *lower_bound(x); if (n == 2) return 1LL;
if(l > v || r < u || _max[id] <= val) return; return l.k * x + l.m;
if(l >= u && r <= v && _semax[id] < val){ const int lim = int(sqrt(n));
st[id] -= cntmax[id] * (_max[id] - val);
} int vsz = (lim + 1) >> 1;
_max[id] = val; }; vector<int> smalls(vsz);
if(l == r) _min[id] = val; for (int i = 0; i < vsz ; ++i) smalls[i] = i;
else{ vector <int> roughs(vsz);
if(_min[id] > val) _min[id] = val; Treap.h for(int cx = 0; cx < vsz; ++cx) roughs[cx]= (cx << 1 | 1);
else if(_semin[id] > val) _semin[id] = val; vector <ll> larges(vsz);
Description: A short self-balancing tree. It acts as a sequential container
} for (int cx = 0; cx < vsz;++cx) larges[cx] = (n / (cx << 1 | 1) - 1) >> 1;
with log-time splits/joins, and is easy to augment with additional data. vector <bool> skips(lim+1);
return;
}
Time: O (log N ) 9556fc, 55 lines int pCnt=0;
down(id, l, r); for(int p=3;p<=lim;p+=2){
struct Node { if (skips[p]) continue;
int mid = (l + r) / 2;
upd_chmin(id * 2, l, mid, u, v, val);
Node *l = 0, *r = 0; int p2 = p * p;
upd_chmin(id * 2 + 1, mid + 1, r, u, v, val); int val, y, c = 1; if(1LL * p2 * p2 > n) break;
combine(id); Node(int val) : val(val), y(rand()) {} skips[p] = true;
} void recalc(); for(int cx = p2; cx <= lim; cx += (p << 1))
void upd_sum(int id, int l, int r, int u, int v, int val){ }; skips[cx] = true;
if(l > v || r < u) return; int ns = 0;
if(l >= u && r <= v){ for(int cx = 0; cx < vsz; ++cx){
int cnt(Node* n) { return n ? n->c : 0; } int cur = roughs[cx];
st[id] += (r - l + 1) * val;
lazy[id] += val;
void Node::recalc() { c = cnt(l) + cnt(r) + 1; } if(skips[cur]) continue;
_max[id] += val; ll d = 1LL * cur * p;
_min[id] += val; template<class F> void each(Node* n, F f) { larges[ns]=larges[cx]-(d<=lim?larges[smalls[d>>1]-pCnt]
if(_semax[id] != -oo) _semax[id] += val; if (n) { each(n->l, f); f(n->val); each(n->r, f); } :smalls[(ll((double(n)/d)-1))>>1])+pCnt;
if(_semin[id] != oo) _semin[id] += val; } roughs[ns++]=cur;
return; }
} vsz=ns;
pair<Node*, Node*> split(Node* n, int k) { for(int cx=(lim-1)>>1,cy=((lim/p)-1)|1;cy>=p;cy-=2){
int mid = (l + r) / 2;
down(id, l, r);
if (!n) return {}; int cur=smalls[cy>>1]-pCnt;
upd_sum(id * 2, l, mid, u, v, val); if (cnt(n->l) >= k) { // ”n−>val >= k” for lower bound(k) for(int cz=(cy*p)>>1;cz<=cx;--cx)
upd_sum(id * 2 + 1, mid + 1, r, u, v, val); auto pa = split(n->l, k); smalls[cx]-=cur;
combine(id); n->l = pa.second; }
} n->recalc(); ++pCnt;
int get(int id, int l, int r, int u, int v){ }
return {pa.first, n}; larges[0]+=1LL*(vsz+((pCnt-1)<<1))*(vsz-1)>>1;
if(l > v || r < u) return 0; } else {
if(l >= u && r <= v) return st[id]; for(int cx=1;cx<vsz;++cx) larges[0]-=larges[cx];
int mid = (l + r) / 2;
auto pa = split(n->r, k - cnt(n->l) - 1); // and j u s t ”k” for(int cx=1;cx<vsz;++cx){
down(id, l, r); n->r = pa.first; int q=roughs[cx];
return get(id * 2, l, mid, u, v) + get(id * 2 + 1, mid + 1, r, u, v); n->recalc(); ll m=n/q;
} return {n, pa.second}; int e=smalls[((m/q)-1)>>1]-pCnt;
}; } if(e<cx+1) break;
ll t=0;
} for(int cy=cx+1;cy<=e;++cy)
LineContainer.h t+=smalls[ll((double(m)/roughs[cy])-1)>>1];
Description: Container where you can add lines of the form kx+m, and Node* merge(Node* l, Node* r) { larges[0]+=t-1LL*(e-cx)*(pCnt+cx-1);
query maximum values at points x. Useful for dynamic programming (“con- if (!l) return r; }
vex hull trick”). if (!r) return l; return larges[0]+1;
Time: O (log N ) if (l->y > r->y) { }
8ec1c7, 30 lines
l->r = merge(l->r, r);
struct Line {
mutable ll k, m, p;
l->recalc(); DynamicWaveletTree.h
bool operator<(const Line& o) const { return k < o.k; }
return l; Description: Given an array of n elements with q queries l, r, k. For each query print
bool operator<(ll x) const { return p < x; }
} else { the kth values if the subsequence [l, r] is sorted increasingly and the sum from the 1st to
};
r->l = merge(l, r->l); kth numbers. Calculate the position of k in the subsequence [l, r]
r->recalc();
Time: O (n log amax) 08bf48, 13 lines
return r;
struct LineContainer : multiset<Line, less<>> {
} struct WaveletTree{
// ( for doubles , use i nf = 1/.0 , div (a , b) = a/b) struct TNode{
}
static const ll inf = LLONG_MAX; int l, r;
ll div(ll a, ll b) { // floored division Node* ins(Node* t, Node* n, int pos) {
int lp, rp;
return a / b - ((a ^ b) < 0 && a % b); } auto pa = split(t, pos); TNode(){
bool isect(iterator x, iterator y) { return merge(merge(pa.first, n), pa.second); l = r = lp = rp = 0;
if (y == end()) return x->p = inf, 0; } }
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf; // Example application : move the range [ l , r ) to index k TNode(int _l, int _r){
void move(Node*& t, int l, int r, int k) { l = _l;
else x->p = div(y->m - x->m, x->k - y->k); r = _r;
return x->p >= y->p; Node *a, *b, *c;
}
} tie(a,b) = split(t, l); tie(b,c) = split(b, r - l); };
void add(ll k, ll m) { if (k <= l) t = merge(ins(a, b, k), c); vector <vector <int>> val;
auto z = insert({k, m, 0}), y = z++, x = y; else t = merge(a, ins(c, b, k - r)); vector <vector <ll>> sum;
while (isect(y, z)) z = erase(z); } vector <int> b;
KTH Polynomial PolyRoots PolyInterpolate BerlekampMassey LinearRecurrence 5
vector <TNode> wt;
return res;
int wt_sz;
} PolyInterpolate.h
WaveletTree(){ Description: Given n points (x[i], y[i]), computes an n-1-degree polynomial
};
wt_sz = 1;
} p that passes through them: p(x) = a[0] ∗ x0 + ... + a[n − 1] ∗ xn−1 . For
void Assign(int _n = 0){ numerical precision, pick x[k] = c ∗ cos(k/(n − 1) ∗ π), k = 0 . . . n − 1.
Time: O n2
val.resize(_n * 4); 08bf48, 13 lines
sum.resize(_n * 4);
wt.resize(_n * 4); typedef vector<double> vd;
} vd interpolate(vd x, vd y, int n) {
template <class T> void build(int id, T i, T j, int l, int r){ vd res(n), temp(n);
wt[id].l = l; rep(k,0,n-1) rep(i,k+1,n)
wt[id].r = r; y[i] = (y[i] - y[k]) / (x[i] - x[k]);
if (l == r){
double last = 0; temp[0] = 1;
return;
} rep(k,0,n) rep(i,0,n) {
val[id].pb(0); res[i] += y[k] * temp[i];
sum[id].pb(0); swap(last, temp[i]);
int mid = (l + r - (l + r < 0)) / 2; temp[i] -= last * x[k];
int maxx = l;
int minn = r; Numerical (4) }
return res;
for (auto it = i; it != j; ++it){
}
val[id].pb(val[id].back() + (*it <= mid));
sum[id].pb(sum[id].back() + *it * (*it <= mid));
4.1 Polynomials and recurrences
if (*it <= mid) maxx = max(maxx, *it); BerlekampMassey.h
else minn = min(minn, *it); Polynomial.h Description: Recovers any n-order linear recurrence relation from the first
} c9b7b0, 17 lines
2n terms of the recurrence. Useful for guessing linear recurrences after brute-
auto p = stable_partition(i, j,[=](const auto &w){ struct Poly {
return w <= mid;
forcing the first terms. Should work on any field, but numerical stability for
vector<double> a; floats is not guaranteed. Output will have size ≤ n.
}); double operator()(double x) const {
wt[id].lp = ++wt_sz; Usage: berlekampMassey({0, 1, 1, 3, 5, 11}) // {1, 2}
wt[id].rp = ++wt_sz; double val = 0; Time: O N 2
build(wt[id].lp, i, p, l, maxx); for (int i = sz(a); i--;) (val *= x) += a[i]; "../number-theory/ModPow.h" 96548b, 20 lines
build(wt[id].rp, p, j, minn, r); return val;
} } vector<ll> berlekampMassey(vector<ll> s) {
ll pos(int k, int i, int j){ void diff() { int n = sz(s), L = 0, m = 0;
--i; rep(i,1,sz(a)) a[i-1] = i*a[i]; vector<ll> C(n), B(n), T;
ll cnt = 0; C[0] = B[0] = 1;
a.pop_back();
int id = 1;
int l = wt[id].l, r = wt[id].r; }
void divroot(double x0) { ll b = 1;
while (l < r){ rep(i,0,n) { ++m;
int mid = (l + r - (l + r < 0)) / 2; double b = a.back(), c; a.back() = 0;
if (k <= mid){ for(int i=sz(a)-1; i--;) c = a[i], a[i] = a[i+1]*x0+b, b=c; ll d = s[i] % mod;
i = val[id][i]; a.pop_back(); rep(j,1,L+1) d = (d + C[j] * s[i - j]) % mod;
j = val[id][j]; } if (!d) continue;
id = wt[id].lp; T = C; ll coef = d * modpow(b, mod-2) % mod;
};
} rep(j,m,n) C[j] = (C[j] - coef * B[j - m]) % mod;
else{ if (2 * L > i) continue;
cnt += val[id][j] - val[id][i]; PolyRoots.h L = i + 1 - L; B = T; b = d; m = 0;
i -= val[id][i]; Description: Finds the real roots to a polynomial.
j -= val[id][j];
}
id = wt[id].rp;
Usage: polyRoots({{2,-3,1}},-1e9,1e9) // solve xˆ2-3x+2 = 0
Time: O n2 log(1/)
} C.resize(L + 1); C.erase(C.begin());
l = wt[id].l, r = wt[id].r; "Polynomial.h" b00bfe, 23 lines for (ll& x : C) x = (mod - x) % mod;
} vector<double> polyRoots(Poly p, double xmin, double xmax) { return C;
if (k >= l) cnt += j - i; if (sz(p.a) == 2) { return {-p.a[0]/p.a[1]}; } }
return cnt;
}
vector<double> ret;
ll get(int k, int i, int j){ Poly der = p; LinearRecurrence.h
if (k == 0) return 0; der.diff(); Description: Generates the k’th term of an n-order linear recurrence
--i; auto dr = polyRoots(der, xmin, xmax); P
S[i] = j S[i − j − 1]tr[j], given S[0 . . . ≥ n − 1] and tr[0 . . . n − 1]. Faster
ll res = 0; dr.push_back(xmin-1);
int id = 1; than matrix multiplication. Useful together with Berlekamp–Massey.
dr.push_back(xmax+1); Usage: linearRec({0, 1}, {1, 1}, k) // k’th Fibonacci number
int l = wt[id].l, r = wt[id].r; sort(all(dr)); Time: O n2 log k
while (l < r){ f4e444, 26 lines
if (k <= val[id][j] - val[id][i]){
rep(i,0,sz(dr)-1) {
i = val[id][i]; double l = dr[i], h = dr[i+1]; typedef vector<ll> Poly;
j = val[id][j]; bool sign = p(l) > 0; ll linearRec(Poly S, Poly tr, ll k) {
id = wt[id].lp; if (sign ^ (p(h) > 0)) { int n = sz(tr);
} rep(it,0,60) { // while (h − l > 1e−8)
else{ double m = (l + h) / 2, f = p(m); auto combine = [&](Poly a, Poly b) {
res += sum[id][j] - sum[id][i]; if ((f <= 0) ^ sign) l = m; Poly res(n * 2 + 1);
k -= val[id][j] - val[id][i];
i -= val[id][i];
else h = m; rep(i,0,n+1) rep(j,0,n+1)
j -= val[id][j]; } res[i + j] = (res[i + j] + a[i] * b[j]) % mod;
id = wt[id].rp; ret.push_back((l + h) / 2); for (int i = 2 * n; i > n; --i) rep(j,0,n)
} } res[i - 1 - j] = (res[i - 1 - j] + res[i] * tr[j]) % mod;
l = wt[id].l, r = wt[id].r; } res.resize(n + 1);
}
return ret; return res;
res += k * l;
} };
KTH GoldenSectionSearch HillClimbing Integrate IntegrateAdaptive Simplex Determinant IntDeterminant 6
rep(i,1,n*2) rep(j,0,n+2) if (j != s) D[r][j] *= inv;
Poly pol(n + 1), e(pol); v += f(a + i*h) * (i&1 ? 4 : 2); rep(i,0,m+2) if (i != r) D[i][s] *= -inv;
pol[0] = e[1] = 1; return v * h / 3; D[r][s] = inv;
} swap(B[r], N[s]);
for (++k; k; k /= 2) { }
if (k % 2) pol = combine(pol, e);
e = combine(e, e); IntegrateAdaptive.h bool simplex(int phase) {
} Description: Fast integration using an adaptive Simpson’s rule. int x = m + phase - 1;
Usage: double sphereVolume = quad(-1, 1, [](double x) { for (;;) {
ll res = 0; return quad(-1, 1, [&](double y) { int s = -1;
rep(i,0,n) res = (res + pol[i + 1] * S[i]) % mod; return quad(-1, 1, [&](double z) { rep(j,0,n+1) if (N[j] != -phase) ltj(D[x]);
return res; return x*x + y*y + z*z < 1; });});}); 92dd79, 15 lines if (D[x][s] >= -eps) return true;
} typedef double d; int r = -1;
#define S(a,b) (f(a) + 4*f((a+b) / 2) + f(b)) * (b-a) / 6 rep(i,0,m) {
if (D[i][s] <= eps) continue;
4.2 Optimization template <class F> if (r == -1 || MP(D[i][n+1] / D[i][s], B[i])
< MP(D[r][n+1] / D[r][s], B[r])) r = i;
d rec(F& f, d a, d b, d eps, d S) {
d c = (a + b) / 2; }
GoldenSectionSearch.h d S1 = S(a, c), S2 = S(c, b), T = S1 + S2; if (r == -1) return false;
Description: Finds the argument minimizing the function f in the inter- if (abs(T - S) <= 15 * eps || b - a < 1e-10) pivot(r, s);
val [a, b] assuming f is unimodal on the interval, i.e. has only one local return T + (T - S) / 15; }
minimum. The maximum error in the result is eps. Works equally well for return rec(f, a, c, eps / 2, S1) + rec(f, c, b, eps / 2, S2); }
maximization with a small change in the code. See TernarySearch.h in the }
Various chapter for a discrete version. template<class F> T solve(vd &x) {
Usage: double func(double x) { return 4+x+.3*x*x; } d quad(d a, d b, F f, d eps = 1e-8) { int r = 0;
double xmin = gss(-1000,1000,func); return rec(f, a, b, eps, S(a, b)); rep(i,1,m) if (D[i][n+1] < D[r][n+1]) r = i;
Time: O (log((b − a)/)) 31d45b, 14 lines } if (D[r][n+1] < -eps) {
double gss(double a, double b, double (*f)(double)) { pivot(r, n);
double r = (sqrt(5)-1)/2, eps = 1e-7; if (!simplex(2) || D[m+1][n+1] < -eps) return -inf;
Simplex.h rep(i,0,m) if (B[i] == -1) {
double x1 = b - r*(b-a), x2 = a + r*(b-a);
Description: Solves a general linear maximization problem: maximize cT x int s = 0;
double f1 = f(x1), f2 = f(x2);
subject to Ax ≤ b, x ≥ 0. Returns -inf if there is no solution, inf if there rep(j,1,n+1) ltj(D[i]);
while (b-a > eps)
are arbitrarily good solutions, or the maximum value of cT x otherwise. The pivot(i, s);
if (f1 < f2) { //change to > to find maximum
input vector is set to an optimal x (or in the unbounded case, an arbitrary }
b = x2; x2 = x1; f2 = f1;
solution fulfilling the constraints). Numerical stability is not guaranteed. For }
x1 = b - r*(b-a); f1 = f(x1);
better performance, define variables such that x = 0 is viable. bool ok = simplex(1); x = vd(n);
} else {
Usage: vvd A = {{1,-1}, {-1,1}, {-1,-2}}; rep(i,0,m) if (B[i] < n) x[B[i]] = D[i][n+1];
a = x1; x1 = x2; f1 = f2;
vd b = {1,1,-4}, c = {-1,-1}, x; return ok ? D[m][n+1] : inf;
x2 = a + r*(b-a); f2 = f(x2);
T val = LPSolver(A, b, c).solve(x); }
}
Time: O (N M ∗ #pivots), where a pivot may be e.g. an edge relaxation. };
return a;
O (2n ) in the general case.
} aa8530, 68 lines
ModMulLL.h } ll crt(ll a, ll m, ll b, ll n) {
Description: Calculate a·b mod c (or ab mod c) for 0 ≤ a, b ≤ c ≤ 7.2·1018 . for (int i : pr) isPrime[i] = 1; if (n > m) swap(a, b), swap(m, n);
Time: O (1) for modmul, O (log b) for modpow return pr; ll x, y, g = euclid(m, n, x, y);
bbbd8f, 11 lines } assert((a - b) % g == 0); // e l s e no solution
typedef unsigned long long ull; x = (b - a) % n * x % n / g * m + a;
ull modmul(ull a, ull b, ull M) { MillerRabin.h return x < 0 ? x + m*n/g : x;
ll ret = a * b - M * ull(1.L / M * a * b); Description: Deterministic Miller-Rabin primality test. Guaranteed to }
return ret + M * (ret < 0) - M * (ret >= (ll)M); work for numbers up to 7 · 1018 ; for larger numbers, use Python and ex-
} tend A randomly.
ull modpow(ull b, ull e, ull mod) { Time: 7 times the complexity of ab mod c. 5.3.1 Bézout’s identity
ull ans = 1; "ModMulLL.h" 60dcd1, 12 lines
for (; e; b = modmul(b, b, mod), e /= 2)
if (e & 1) ans = modmul(ans, b, mod);
bool isPrime(ull n) { For a 6=, b 6= 0, then d = gcd(a, b) is the smallest positive integer
if (n < 2 || n % 6 % 4 != 1) return (n | 1) == 3; for which there are integer solutions to
return ans;
ull A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
}
s = __builtin_ctzll(n-1), d = n >> s;
for (ull a : A) { // ^ count t r a i l i n g zeroes
ax + by = d
ModSqrt.h ull p = modpow(a%n, d, n), i = s;
Description: Tonelli-Shanks algorithm for modular square roots. Finds x while (p != 1 && p != n - 1 && a % n && i--) If (x, y) is one solution, then all solutions are given by
s.t. x2 = a (mod p) (−x gives the other solution). p = modmul(p, p, n);
Time: O log2 p worst case, O (log p) for most p
if (p != n-1 && i != s) return 0; kb ka
"ModPow.h" 19a793, 24 lines } x+ ,y − , k∈Z
ll sqrt(ll a, ll p) { return 1;
gcd(a, b) gcd(a, b)
a %= p; if (a < 0) a += p; }
if (a == 0) return 0; phiFunction.h
assert(modpow(a, (p-1)/2, p) == 1); // e l s e no solution Factor.h Description: Euler’s φ function is defined as φ(n) := # of positive integers
if (p % 4 == 3) return modpow(a, (p+1)/4, p); Description: Pollard-rho randomized factorization algorithm. Returns ≤ n that are coprime with n. φ(1) = 1, p prime ⇒ φ(pk ) = (p − 1)pk−1 ,
// a^(n+3)/8 or 2^(n+3)/8 ∗ 2^(n−1)/4 works i f p % 8 == 5
ll s = p - 1, n = 2; ofa number, in arbitrary order (e.g. 2299 -> {11, 19, 11}).
prime factors k
m, n coprime ⇒ φ(mn) = φ(m)φ(n). If n = p1 1 p2 2 ...pk
k
r
r then φ(n) =
Time: O n1/4 , less for numbers with small factors. k1 −1 kr −1 Q
int r = 0, m; (p1 − 1)p1 ...(pr − 1)pr . φ(n) = n · p|n (1 − 1/p).
while (s % 2 == 0) "ModMulLL.h", "MillerRabin.h" a33cf6, 18 lines P P
d|n φ(d) = n, 1≤k≤n,gcd(k,n)=1 k = nφ(n)/2, n > 1
++r, s /= 2; ull pollard(ull n) {
while (modpow(n, (p - 1) / 2, p) != p - 1) ++n; auto f = [n](ull x) { return modmul(x, x, n) + 1; }; Euler’s thm: a, n coprime ⇒ aφ(n) ≡ 1 (mod n).
ll x = modpow(a, (s + 1) / 2, p); ull x = 0, y = 0, t = 30, prd = 2, i = 1, q; Fermat’s little thm: p prime ⇒ ap−1 ≡ 1 (mod p) ∀a. cf7d6d, 8 lines
ll b = modpow(a, s, p), g = modpow(n, s, p); while (t++ % 40 || __gcd(prd, n) == 1) {
const int LIM = 5000000;
for (;; r = m) { if (x == y) x = ++i, y = f(x);
int phi[LIM];
ll t = b; if ((q = modmul(prd, max(x,y) - min(x,y), n))) prd = q;
for (m = 0; m < r && t != 1; ++m) x = f(x), y = f(f(y));
void calculatePhi() {
t = t * t % p; }
rep(i,0,LIM) phi[i] = i&1 ? i : i/2;
if (m == 0) return x; return __gcd(prd, n);
for (int i = 3; i < LIM; i += 2) if(phi[i] == i)
ll gs = modpow(g, 1LL << (r - m - 1), p); }
for (int j = i; j < LIM; j += i) phi[j] -= phi[j] / i;
g = gs * gs % p; vector<ull> factor(ull n) {
}
x = x * gs % p; if (n == 1) return {};
KTH ContinuedFractions FracBinarySearch IntPerm 10
5.4 Fractions 5.5 Pythagorean Triples IntPerm.h
Description: Permutation -> integer conversion. (Not order preserving.)
The Pythagorean triples are uniquely generated by Integer -> permutation can use a lookup table.
Time: O (n) 044568, 6 lines
bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); } auto oa = c.cross(d, a), ob = c.cross(d, b), typedef Point<double> P;
P operator+(P p) const { return P(x+p.x, y+p.y); } oc = a.cross(b, c), od = a.cross(b, d); P linearTransformation(const P& p0, const P& p1,
KTH Angle CircleIntersection CircleTangents CirclePolygonIntersection circumcircle MinimumEnclosingCircle InsidePolygon PolygonArea PolygonCenter 18
const P& q0, const P& q1, const P& r) { CircleTangents.h MinimumEnclosingCircle.h
P dp = p1-p0, dq = q1-q0, num(dp.cross(dq), dp.dot(dq)); Description: Finds the external tangents of two circles, or internal if r2 is Description: Computes the minimum circle that encloses a set of points.
return q0 + P((r-p0).cross(num), (r-p0).dot(num))/dp.dist2(); negated. Can return 0, 1, or 2 tangents – 0 if one circle contains the other (or Time: expected O (n)
} overlaps it, in the internal case, or if the circles are the same); 1 if the circles "circumcircle.h" 09dd0a, 17 lines
are tangent to each other (in which case .first = .second and the tangent line pair<P, double> mec(vector<P> ps) {
is perpendicular to the line between the centers). .first and .second give the
Angle.h tangency points at circle 1 and 2 respectively. To find the tangents of a circle
shuffle(all(ps), mt19937(time(0)));
Description: A class for ordering angles (as represented by int points and P o = ps[0];
with a point set r2 to 0. double r = 0, EPS = 1 + 1e-8;
a number of rotations around the origin). Useful for rotational sweeping.
"Point.h" b0153d, 13 lines rep(i,0,sz(ps)) if ((o - ps[i]).dist() > r * EPS) {
Sometimes also represents points or vectors.
Usage: vector<Angle> v = {w[0], w[0].t360() ...}; // sorted template<class P> o = ps[i], r = 0;
int j = 0; rep(i,0,n) { while (v[j] < v[i].t180()) ++j; } vector<pair<P, P>> tangents(P c1, double r1, P c2, double r2) { rep(j,0,i) if ((o - ps[j]).dist() > r * EPS) {
// sweeps j such that (j-i) represents the number of positively P d = c2 - c1; o = (ps[i] + ps[j]) / 2;
oriented triangles with vertices at 0 and i double dr = r1 - r2, d2 = d.dist2(), h2 = d2 - dr * dr; r = (o - ps[i]).dist();
0f0602, 35 lines
if (d2 == 0 || h2 < 0) return {}; rep(k,0,j) if ((o - ps[k]).dist() > r * EPS) {
struct Angle { vector<pair<P, P>> out; o = ccCenter(ps[i], ps[j], ps[k]);
int x, y; for (double sign : {-1, 1}) { r = (o - ps[i]).dist();
int t; P v = (d * dr + d.perp() * sqrt(h2) * sign) / d2; }
Angle(int x, int y, int t=0) : x(x), y(y), t(t) {} out.push_back({c1 + v * r1, c2 + v * r2}); }
Angle operator-(Angle b) const { return {x-b.x, y-b.y, t}; } } }
int half() const { if (h2 == 0) out.pop_back(); return {o, r};
assert(x || y); return out; }
return y < 0 || (y == 0 && x < 0); }
}
Angle t90() const { return {-y, x, t + (half() && x >= 0)}; }
Angle t180() const { return {-x, -y, t + half()}; }
8.3 Polygons
Angle t360() const { return {x, y, t + 1}; } CirclePolygonIntersection.h
}; Description: Returns the area of the intersection of a circle with a ccw InsidePolygon.h
bool operator<(Angle a, Angle b) { polygon. Description: Returns true if p lies within the polygon. If strict is true, it
// add a . dist2 () and b . dist2 () to also compare distances Time: O (n) returns false for points on the boundary. The algorithm uses products in
return make_tuple(a.t, a.half(), a.y * (ll)b.x) < "../../content/geometry/Point.h" a1ee63, 19 lines intermediate steps so watch out for overflow.
make_tuple(b.t, b.half(), a.x * (ll)b.y); Usage: vector<P> v = {P{4,4}, P{1,2}, P{2,1}};
typedef Point<double> P;
} bool in = inPolygon(v, P{3, 3}, false);
#define arg(p, q) atan2(p.cross(q), p.dot(q))
Time: O (n)
double circlePoly(P c, double r, vector<P> ps) {
// Given two points , t h i s calculates the smallest angle between auto tri = [&](P p, P q) {
"Point.h", "OnSegment.h", "SegmentDistance.h" 2bf504, 11 lines
// them, i . e . , the angle that covers the defined l i n e segment . auto r2 = r * r / 2; template<class P>
pair<Angle, Angle> segmentAngles(Angle a, Angle b) { P d = q - p; bool inPolygon(vector<P> &p, P a, bool strict = true) {
if (b < a) swap(a, b); auto a = d.dot(p)/d.dist2(), b = (p.dist2()-r*r)/d.dist2(); int cnt = 0, n = sz(p);
return (b < a.t180() ? auto det = a * a - b; rep(i,0,n) {
make_pair(a, b) : make_pair(b, a.t360())); if (det <= 0) return arg(p, q) * r2; P q = p[(i + 1) % n];
} auto s = max(0., -a-sqrt(det)), t = min(1., -a+sqrt(det)); if (onSegment(p[i], q, a)) return !strict;
Angle operator+(Angle a, Angle b) { // point a + vector b if (t < 0 || 1 <= s) return arg(p, q) * r2; //or : i f ( segDist (p [ i ] , q , a) <= eps) return ! s t r i c t ;
Angle r(a.x + b.x, a.y + b.y, a.t); P u = p + d * s, v = p + d * t; cnt ^= ((a.y<p[i].y) - (a.y<q.y)) * a.cross(p[i], q) > 0;
if (a.t180() < r) r.t--; return arg(p,u) * r2 + u.cross(v)/2 + arg(v,q) * r2; }
return r.t180() < a ? r.t360() : r; }; return cnt;
} auto sum = 0.0; }
Angle angleDiff(Angle a, Angle b) { // angle b − angle a rep(i,0,sz(ps))
int tu = b.t - a.t; a.t = b.t;
return {a.x*b.x + a.y*b.y, a.x*b.y - a.y*b.x, tu - (b < a)};
sum += tri(ps[i] - c, ps[(i + 1) % sz(ps)] - c); PolygonArea.h
return sum; Description: Returns twice the signed area of a polygon. Clockwise enu-
} } meration gives negative area. Watch out for overflow if using int as T!
"Point.h" f12300, 6 lines
template<class T>
8.2 Circles T polygonArea2(vector<Point<T>>& v) {
circumcircle.h T a = v.back().cross(v[0]);
Description:
CircleIntersection.h B rep(i,0,sz(v)-1) a += v[i].cross(v[i+1]);
Description: Computes the pair of points at which two circles intersect. The circumcirle of a triangle is the circle intersecting all return a;
Returns false in case of no intersection. three vertices. ccRadius returns the radius of the circle going r c }
"Point.h" 84d6d3, 11 lines through points A, B and C and ccCenter returns the center C
of the same circle. A
typedef Point<double> P;
"Point.h" 1caa3a, 9 lines
PolygonCenter.h
bool circleInter(P a,P b,double r1,double r2,pair<P, P>* out) { Description: Returns the center of mass for a polygon.
if (a == b) { assert(r1 != r2); return false; } typedef Point<double> P; Time: O (n)
P vec = b - a; double ccRadius(const P& A, const P& B, const P& C) { "Point.h" 9706dc, 9 lines
double d2 = vec.dist2(), sum = r1+r2, dif = r1-r2, return (B-A).dist()*(C-B).dist()*(A-C).dist()/
typedef Point<double> P;
p = (d2 + r1*r1 - r2*r2)/(d2*2), h2 = r1*r1 - p*p*d2; abs((B-A).cross(C-A))/2;
P polygonCenter(const vector<P>& v) {
if (sum*sum < d2 || dif*dif > d2) return false; }
P res(0, 0); double A = 0;
P mid = a + vec*p, per = vec.perp() * sqrt(fmax(0, h2) / d2); P ccCenter(const P& A, const P& B, const P& C) {
for (int i = 0, j = sz(v) - 1; i < sz(v); j = i++) {
*out = {mid + per, mid - per}; P b = C-A, c = B-A;
res = res + (v[i] + v[j]) * v[j].cross(v[i]);
return true; return A + (b*c.dist2()-c*b.dist2()).perp()/b.cross(c)/2;
A += v[j].cross(v[i]);
} }
}
KTH PolygonCut ConvexHull HullDiameter PointInsideHull LineHullIntersection ClosestPair kdTree 19
return res / A / 3; Time: O (log N ) 8.4 Misc. Point Set Problems
} "Point.h", "sideOf.h", "OnSegment.h" 71446b, 14 lines
AhoCorasick.h
Time: construction takes O (26N ), where N = sum of length of patterns.
Dinitz.h find(x) is O (N ), where N = length of x. findAll is O (N M ). f35677, 66 lines
3f02d8, 44 lines
struct Edge{ struct node{
int u, v; int link = -1, nxt[27], par, ch, go[27], val = -1, leaf = 0;
ll c; node(int par = -1,char ch = 'a') : par(par), ch(ch){
Edge() {} memset(nxt, -1, sizeof(nxt));
Edge(int u, int v, ll c){ memset(go, -1, sizeof(go));
this->u = u; }
this->v = v; };
this->c = c; struct Aho_Corasick{
} vector<node> aho;
}; void init(){
struct Dinic{ aho.clear();
const ll Inf = 1e17; aho.emplace_back(-1, 'a');
int n, sink, source; }
vector<vector<int>> adj; int add(string s, int val){
vector<Edge> s; int now = 0;
vector<int> h; for(char c : s){
vector<vector<int>::iterator> cur; if(aho[now].nxt[c - 'a' + 1] == -1){
void Assign(int n = 0){ aho[now].nxt[c - 'a' + 1] = aho.size();
this->n = n; aho.emplace_back(now, c);
adj.resize(n + 2); }
s.reserve(n + 2); now = aho[now].nxt[c - 'a' + 1];
cur.resize(n + 2); }
h.resize(n + 2); aho[now].leaf = val;
} return now;
void AddEdge(int u, int v, ll c){ }
s.emplace_back(u, v, c); int get_val(int u){
adj[u].emplace_back(s.size() - 1); if(u == 0) return 0;
s.emplace_back(v, u, 0); if(aho[u].val == -1){
adj[v].emplace_back(s.size() - 1); aho[u].val = aho[u].leaf + get_val(get_link(u));
} }
bool BFS(){
fill(h.begin(), h.end(), n + 2); }
return aho[u].val; IntervalContainer.h
Time: O (log N ) edce47, 23 lines
queue<int> q({sink}); int go(int v,int t){ set<pii>::iterator addInterval(set<pii>& is, int L, int R) {
h[sink] = 0; if(aho[v].go[t] == -1){ if (L == R) return is.end();
while(!q.empty()){ if(aho[v].nxt[t] != -1){
auto it = is.lower_bound({L, R}), before = it;
int c = q.front(); q.pop(); aho[v].go[t]=aho[v].nxt[t];
for(auto i : adj[c]) } while (it != is.end() && it->first <= R) {
if(h[s[i].v] == n + 2 && s[i ^ 1].c != 0){ else{ R = max(R, it->second);
h[s[i].v] = h[c] + 1; if(v == 0) aho[v].go[t] = 0; before = it = is.erase(it);
if(s[i].v == source) return true; else aho[v].go[t] = go(get_link(v), t); }
q.emplace(s[i].v); } if (it != is.begin() && (--it)->second >= L) {
} } L = min(L, it->first);
} return aho[v].go[t];
R = max(R, it->second);
return false; }
} int get_link(int v){ is.erase(it);
ll dfs(int v, ll flowin){ if(aho[v].link == -1){ }
if(v == sink) return flowin; if(aho[v].par == 0 || v == 0) aho[v].link = 0; return is.insert(before, {L,R});
ll flowout(0); else aho[v].link = go(get_link(aho[v].par), aho[v].ch - 'a' + 1); }
for(; cur[v] != adj[v].end(); ++cur[v]){ }
int i = *cur[v]; return aho[v].link; void removeInterval(set<pii>& is, int L, int R) {
if(s[i].c == 0 | h[s[i].v] + 1 != h[v]) continue; }
if (L == R) return;
ll q = dfs(s[i].v, min(flowin, s[i].c)); int get(string s){
int now = 0; auto it = addInterval(is, L, R);
flowout += q; int res = 0; auto r2 = it->second;
if(flowin != Inf) flowin -= q; for(char c : s){ if (it->first == L) is.erase(it);
s[i].c -= q; now = go(now, c - 'a' + 1); else (int&)it->second = L;
s[i ^ 1].c += q; res += get_val(now); if (R != r2) is.emplace(R, r2);
if(flowin == 0) break; } }
} return res;
return flowout; }
} }; IntervalCover.h
ll BlockFlow(){ Description: Compute indices of smallest set of intervals covering another
for(int i = 1; i <= n; ++i) cur[i] = adj[i].begin(); interval. Intervals should be [inclusive, exclusive). To support [inclusive,
return dfs(source, Inf);
inclusive], change (A) to add || R.empty(). Returns empty set on failure
}
ll MaxFlow(int s, int t){ (or if G is empty).
sink = t; Time: O (N log N ) 9e9d8d, 19 lines
source = s;
ll Flow(0); template<class T>
while(BFS()) Flow += BlockFlow(); vi cover(pair<T, T> G, vector<pair<T, T>> I) {
return Flow; vi S(sz(I)), R;
} iota(all(S), 0);
}; sort(all(S), [&](int a, int b) { return I[a] < I[b]; });
T cur = G.first;
int at = 0;
KTH TernarySearch LIS KnuthDP DivideAndConquerDP FastMod FastInput BumpAllocator ConstantIntervals 23
while (cur < G.second) { // (A) Description: When doing DP on intervals: a[i][j] = mini<k<j (a[i][k] + if (i & 1 << b) D[i] += D[iˆ(1 << b)];
pair<T, int> mx = make_pair(cur, -1); a[k][j]) + f (i, j), where the (minimal) optimal k increases with both i computes all sums of subsets.
while (at < sz(I) && I[S[at]].first <= cur) { and j, one can solve intervals in increasing order of length, and search
mx = max(mx, make_pair(I[S[at]].second, S[at])); k = p[i][j] for a[i][j] only between p[i][j − 1] and p[i + 1][j]. This is
at++; known as Knuth DP. Sufficient criteria for this are if f (b, c) ≤ f (a, d) and 10.5.2 Pragmas
} f (a, c) + f (b, d) ≤ f (a, d) + f (b, c) for all a ≤ b ≤ c ≤ d. Consider also:
if (mx.second == -1) return {}; LineContainer(ch. Data structures), monotone queues, ternary search. • #pragma GCC optimize ("Ofast") will make GCC
cur = mx.first; Time: O N 2
R.push_back(mx.second); auto-vectorize loops and optimizes floating points better.
}
return R; DivideAndConquerDP.h • #pragma GCC target ("avx2") can double performance of
} Description: Given a[i] = minlo(i)≤k<hi(i) (f (i, k)) where the (minimal) vectorized code, but causes crashes on old machines.
optimal k increases with i, computes a[i] for i = L..R − 1.
Time: O ((N + (hi − lo)) log N ) d38d2b, 18 lines • #pragma GCC optimize ("trapv") kills the program on integer
ConstantIntervals.h struct DP { // Modify at w i l l : overflows (but is really slow).
Description: Split a monotone function on [from, to) into a minimal set of int lo(int ind) { return 0; }
int hi(int ind) { return ind; }
half-open intervals on which it has the same value. Runs a callback g for
ll f(int ind, int k) { return dp[ind][k]; } FastMod.h
each such interval. Description: Compute a%b about 5 times faster than usual, where b is
Usage: constantIntervals(0, sz(v), [&](int x){return v[x];}, void store(int ind, int k, ll v) { res[ind] = pii(k, v); }
constant but not known at compile time. Returns a value congruent to a
[&](int lo, int hi, T val){...}); (mod b) in the range [0, 2b).
Time: O k log n void rec(int L, int R, int LO, int HI) { 751a02, 8 lines
k 753a4c, 19 lines if (L >= R) return; typedef unsigned long long ull;
template<class F, class G, class T> int mid = (L + R) >> 1; struct FastMod {
void rec(int from, int to, F& f, G& g, int& i, T& p, T q) { pair<ll, int> best(LLONG_MAX, LO); ull b, m;
if (p == q) return; rep(k, max(LO,lo(mid)), min(HI,hi(mid))) FastMod(ull b) : b(b), m(-1ULL / b) {}
if (from == to) { best = min(best, make_pair(f(mid, k), k)); ull reduce(ull a) { // a % b + (0 or b)
g(i, to, p); store(mid, best.second, best.first); return a - (ull)((__uint128_t(m) * a) >> 64) * b;
i = to; p = q; rec(L, mid, LO, best.second+1); }
} else { rec(mid+1, R, best.second, HI); };
int mid = (from + to) >> 1; }
rec(from, mid, f, g, i, p, f(mid)); void solve(int L, int R) { rec(L, R, INT_MIN, INT_MAX); }
rec(mid+1, to, f, g, i, p, q); }; FastInput.h
} Description: Read an integer from stdin. Usage requires your program to
} pipe in input from file.
template<class F, class G> Usage: ./a.out < input.txt
void constantIntervals(int from, int to, F f, G g) {
10.4 Debugging tricks Time: About 5x as fast as cin/scanf. 7b3c70, 17 lines
if (to <= from) return;
int i = from; auto p = f(i), q = f(to-1); • signal(SIGSEGV, [](int) { _Exit(0); }); inline char gc() { // l i k e getchar ()
rec(from, to-1, f, g, i, p, q); static char buf[1 << 16];
converts segfaults into Wrong Answers. Similarly one can static size_t bc, be;
g(i, to, q);
} catch SIGABRT (assertion failures) and SIGFPE (zero if (bc >= be) {
buf[0] = 0, bc = 0;
divisions). _GLIBCXX_DEBUG failures generate SIGABRT
10.2 Misc. algorithms (or SIGSEGV on gcc 5.4.0 apparently). }
be = fread(buf, 1, sizeof(buf), stdin);