Skip to content

Commit b6f7c82

Browse files
committed
merged
2 parents a8b3ec7 + 2602dc1 commit b6f7c82

File tree

101 files changed

+1364
-559
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1364
-559
lines changed

content/contest/template.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ using namespace std;
33

44
#define rep(i, a, b) for(int i = a; i < (b); ++i)
55
#define trav(a, x) for(auto& a : x)
6-
#define all(x) x.begin(), x.end()
6+
#define all(x) begin(x), end(x)
77
#define sz(x) (int)(x).size()
88
typedef long long ll;
99
typedef pair<int, int> pii;

content/data-structures/OrderStatisticTree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ using namespace __gnu_pbds;
1515

1616
template<class T>
1717
using Tree = tree<T, null_type, less<T>, rb_tree_tag,
18-
tree_order_statistics_node_update>;
18+
tree_order_statistics_node_update>;
1919

2020
void example() {
2121
Tree<int> t, t2; t.insert(8);

content/data-structures/SegmentTree.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
* Date: 2017-10-31
44
* License: CC0
55
* Source: folklore
6-
* Description: Zero-indexed max-tree. Bounds are inclusive to the left and exclusive to the right. Can be changed by modifying T, LOW and f.
6+
* Description: Zero-indexed max-tree. Bounds are inclusive to the left and exclusive to the right. Can be changed by modifying T, f and unit.
77
* Time: O(\log N)
88
* Status: fuzz-tested
99
*/
1010
#pragma once
1111

1212
struct Tree {
1313
typedef int T;
14-
static const T LOW = INT_MIN;
14+
static constexpr T unit = INT_MIN;
1515
T f(T a, T b) { return max(a, b); } // (any associative fn)
1616
vector<T> s; int n;
17-
Tree(int n = 0, T def = 0) : s(2*n, def), n(n) {}
17+
Tree(int n = 0, T def = unit) : s(2*n, def), n(n) {}
1818
void update(int pos, T val) {
19-
for (s[pos += n] = val; pos > 1; pos /= 2)
20-
s[pos / 2] = f(s[pos & ~1], s[pos | 1]);
19+
for (s[pos += n] = val; pos /= 2;)
20+
s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
2121
}
2222
T query(int b, int e) { // query [b, e)
23-
T ra = LOW, rb = LOW;
23+
T ra = unit, rb = unit;
2424
for (b += n, e += n; b < e; b /= 2, e /= 2) {
2525
if (b % 2) ra = f(ra, s[b++]);
2626
if (e % 2) rb = f(s[--e], rb);

content/data-structures/Treap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ template<class F> void each(Node* n, F f) {
2525

2626
pair<Node*, Node*> split(Node* n, int k) {
2727
if (!n) return {};
28-
if (cnt(n->l) >= k) { // "n->val >= v" for lower_bound(v)
28+
if (cnt(n->l) >= k) { // "n->val >= k" for lower_bound(k)
2929
auto pa = split(n->l, k);
3030
n->l = pa.second;
3131
n->recalc();
3232
return {pa.first, n};
3333
} else {
34-
auto pa = split(n->r, k - cnt(n->l) - 1);
34+
auto pa = split(n->r, k - cnt(n->l) - 1); // and just "k"
3535
n->r = pa.first;
3636
n->recalc();
3737
return {n, pa.second};

content/data-structures/UnionFind.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ struct UF {
1414
bool same_set(int a, int b) { return find(a) == find(b); }
1515
int size(int x) { return -e[find(x)]; }
1616
int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
17-
void join(int a, int b) {
17+
bool join(int a, int b) {
1818
a = find(a), b = find(b);
19-
if (a == b) return;
19+
if (a == b) return false;
2020
if (e[a] > e[b]) swap(a, b);
2121
e[a] += e[b]; e[b] = a;
22+
return true;
2223
}
2324
};

content/geometry/Angle.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Author: Simon Lindholm
33
* Date: 2015-01-31
44
* License: CC0
5-
* Source:
5+
* Source: me
66
* Description: A class for ordering angles (as represented by int points and
77
* a number of rotations around the origin). Useful for rotational sweeping.
88
* Sometimes also represents points or vectors.
@@ -19,20 +19,18 @@ struct Angle {
1919
int t;
2020
Angle(int x, int y, int t=0) : x(x), y(y), t(t) {}
2121
Angle operator-(Angle b) const { return {x-b.x, y-b.y, t}; }
22-
int quad() const {
22+
int half() const {
2323
assert(x || y);
24-
if (y < 0) return (x >= 0) + 2;
25-
if (y > 0) return (x <= 0);
26-
return (x <= 0) * 2;
24+
return y < 0 || (y == 0 && x < 0);
2725
}
28-
Angle t90() const { return {-y, x, t + (quad() == 3)}; }
29-
Angle t180() const { return {-x, -y, t + (quad() >= 2)}; }
26+
Angle t90() const { return {-y, x, t + (half() && x >= 0)}; }
27+
Angle t180() const { return {-x, -y, t + half()}; }
3028
Angle t360() const { return {x, y, t + 1}; }
3129
};
3230
bool operator<(Angle a, Angle b) {
3331
// add a.dist2() and b.dist2() to also compare distances
34-
return make_tuple(a.t, a.quad(), a.y * (ll)b.x) <
35-
make_tuple(b.t, b.quad(), a.x * (ll)b.y);
32+
return make_tuple(a.t, a.half(), a.y * (ll)b.x) <
33+
make_tuple(b.t, b.half(), a.x * (ll)b.y);
3634
}
3735

3836
// Given two points, this calculates the smallest angle between

content/geometry/CircleIntersection.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,21 @@
22
* Author: Simon Lindholm
33
* Date: 2015-09-01
44
* License: CC0
5-
* Description: Computes a pair of points at which two circles intersect. Returns false in case of no intersection.
6-
* Status: somewhat tested
5+
* Description: Computes the pair of points at which two circles intersect. Returns false in case of no intersection.
6+
* Status: fuzz-tested
77
*/
88
#pragma once
99

1010
#include "Point.h"
1111

1212
typedef Point<double> P;
13-
bool circleIntersection(P a, P b, double r1, double r2,
14-
pair<P, P>* out) {
15-
P delta = b - a;
16-
assert(delta.x || delta.y || r1 != r2);
17-
if (!delta.x && !delta.y) return false;
18-
double r = r1 + r2, d2 = delta.dist2();
19-
double p = (d2 + r1*r1 - r2*r2) / (2.0 * d2);
20-
double h2 = r1*r1 - p*p*d2;
21-
if (d2 > r*r || h2 < 0) return false;
22-
P mid = a + delta*p, per = delta.perp() * sqrt(h2 / d2);
13+
bool circleInter(P a,P b,double r1,double r2,pair<P, P>* out) {
14+
if (a == b) { assert(r1 != r2); return false; }
15+
P vec = b - a;
16+
double d2 = vec.dist2(), sum = r1+r2, dif = r1-r2,
17+
p = (d2 + r1*r1 - r2*r2)/(d2*2), h2 = r1*r1 - p*p*d2;
18+
if (sum*sum < d2 || dif*dif > d2) return false;
19+
P mid = a + vec*p, per = vec.perp() * sqrt(fmax(0, h2) / d2);
2320
*out = {mid + per, mid - per};
2421
return true;
2522
}

content/geometry/ConvexHull.h

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
2-
* Author: Johan Sannemo
3-
* Date: 2017-04-16
4-
* License: CC0
5-
* Source: Basic algorithm knowledge
2+
* Author: Stjepan Glavina, chilli
3+
* Date: 2019-05-05
4+
* License: Unlicense
5+
* Source: https://github.com/stjepang/snippets/blob/master/convex_hull.cpp
66
* Description:
77
\\\begin{minipage}{75mm}
88
Returns a vector of indices of the convex hull in counter-clockwise order.
@@ -14,32 +14,22 @@ Points on the edge of the hull between two other points are not considered part
1414
\vspace{-6mm}
1515
\end{minipage}
1616
* Status: tested with Kattis problems convexhull
17-
* Usage:
18-
* vector<P> ps, hull;
19-
* trav(i, convexHull(ps)) hull.push_back(ps[i]);
2017
* Time: O(n \log n)
2118
*/
2219
#pragma once
2320

2421
#include "Point.h"
2522

2623
typedef Point<ll> P;
27-
pair<vi, vi> ulHull(const vector<P>& S) {
28-
vi Q(sz(S)), U, L;
29-
iota(all(Q), 0);
30-
sort(all(Q), [&S](int a, int b){ return S[a] < S[b]; });
31-
trav(it, Q) {
32-
#define ADDP(C, cmp) while (sz(C) > 1 && S[C[sz(C)-2]].cross(\
33-
S[it], S[C.back()]) cmp 0) C.pop_back(); C.push_back(it);
34-
ADDP(U, <=); ADDP(L, >=);
35-
}
36-
return {U, L};
37-
}
38-
39-
vi convexHull(const vector<P>& S) {
40-
vi u, l; tie(u, l) = ulHull(S);
41-
if (sz(S) <= 1) return u;
42-
if (S[u[0]] == S[u[1]]) return {0};
43-
l.insert(l.end(), u.rbegin()+1, u.rend()-1);
44-
return l;
24+
vector<P> convexHull(vector<P> pts) {
25+
if (sz(pts) <= 1) return pts;
26+
sort(all(pts));
27+
vector<P> h(sz(pts)+1);
28+
int s = 0, t = 0;
29+
for (int it = 2; it--; s = --t, reverse(all(pts)))
30+
trav(p, pts) {
31+
while (t >= s + 2 && h[t-2].cross(h[t-1], p) <= 0) t--;
32+
h[t++] = p;
33+
}
34+
return {h.begin(), h.begin() + t - (t == 2 && h[0] == h[1])};
4535
}

content/geometry/HullDiameter.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Author: Oleksandr Bacherikov, chilli
3+
* Date: 2019-05-05
4+
* License: Boost Software License
5+
* Source: https://codeforces.com/blog/entry/48868
6+
* Description: Returns the two points with max distance on a convex hull (ccw,
7+
* no duplicate/colinear points).
8+
* Status: Fuzz-tested, submitted on kattis roberthood
9+
*/
10+
#pragma once
11+
12+
typedef Point<ll> P;
13+
array<P, 2> hullDiameter(vector<P> S) {
14+
int n = sz(S), j = n < 2 ? 0 : 1;
15+
pair<ll, array<P, 2>> res({0, {S[0], S[0]}});
16+
rep(i,0,j)
17+
for (;; j = (j + 1) % n) {
18+
res = max(res, {(S[i] - S[j]).dist2(), {S[i], S[j]}});
19+
if ((S[(j + 1) % n] - S[j]).cross(S[i + 1] - S[i]) >= 0)
20+
break;
21+
}
22+
return res.second;
23+
}

content/geometry/InsidePolygon.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Author: Victor Lecomte, chilli
3+
* Date: 2019-04-26
4+
* License: CC0
5+
* Source: https://vlecomte.github.io/cp-geo.pdf
6+
* Description: Returns true if p lies within the polygon. If strict is true,
7+
* it returns false for points on the boundary. The algorithm uses
8+
* products in intermediate steps so watch out for overflow.
9+
* Time: O(n)
10+
* Status: fuzz-tested and Kattis problem pointinpolygon
11+
* Usage:
12+
* vector<P> v = {P{4,4}, P{1,2}, P{2,1}};
13+
* bool in = inPolygon(v, P{3, 3}, false);
14+
*/
15+
#pragma once
16+
17+
#include "Point.h"
18+
#include "OnSegment.h"
19+
#include "SegmentDistance.h"
20+
21+
template<class P>
22+
bool inPolygon(vector<P> &p, P a, bool strict = true) {
23+
int cnt = 0, n = sz(p);
24+
rep(i,0,n) {
25+
P q = p[(i + 1) % n];
26+
if (onSegment(p[i], q, a)) return !strict;
27+
//or: if (segDist(p[i], q, a) <= eps) return !strict;
28+
cnt ^= ((a.y<p[i].y) - (a.y<q.y)) * a.cross(p[i], q) > 0;
29+
}
30+
return cnt;
31+
}

0 commit comments

Comments
 (0)