Skip to content

Commit e165e20

Browse files
committed
Merge remote-tracking branch 'true/master' into polynomial
2 parents ccb400b + c849ad6 commit e165e20

Some content is hidden

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

48 files changed

+604
-365
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
build/
1+
/build/
22
a.out
33
header.tmp
44
.vscode

Makefile

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
1-
LATEXCMD = pdflatex -shell-escape
1+
LATEXCMD = pdflatex -shell-escape -output-directory build/
2+
export TEXINPUTS=.:content/tex/:
23
export max_print_line = 1048576
34

4-
.PHONY: help
55
help:
6-
@echo "This makefile builds KACTL (KTH ACM Contest Template Library)"
6+
@echo "This makefile builds KACTL (KTH Algorithm Competition Template Library)"
77
@echo ""
88
@echo "Available commands are:"
9-
@echo " make fast - to build the KACTL, quickly (only runs LaTeX once)"
10-
@echo " make kactl - to build the KACTL"
9+
@echo " make fast - to build KACTL, quickly (only runs LaTeX once)"
10+
@echo " make kactl - to build KACTL"
1111
@echo " make clean - to clean up the build process"
1212
@echo " make veryclean - to clean up and remove kactl.pdf"
1313
@echo " make help - to show this information"
1414
@echo ""
1515
@echo "For more information see the file 'doc/README'"
1616

17-
.PHONY: fast
18-
fast:
19-
cd build && $(LATEXCMD) kactl.tex </dev/null
17+
fast: | build
18+
$(LATEXCMD) content/kactl.tex </dev/null
2019
cp build/kactl.pdf kactl.pdf
2120

22-
.PHONY: kactl
23-
kactl: test-session.pdf
24-
cd build && $(LATEXCMD) kactl.tex && $(LATEXCMD) kactl.tex
21+
kactl: test-session.pdf | build
22+
$(LATEXCMD) content/kactl.tex && $(LATEXCMD) content/kactl.tex
2523
cp build/kactl.pdf kactl.pdf
2624

27-
.PHONY: clean
2825
clean:
2926
cd build && rm -f kactl.aux kactl.log kactl.tmp kactl.toc kactl.pdf kactl.ptc
3027

31-
.PHONY: veryclean
3228
veryclean: clean
3329
rm -f kactl.pdf test-session.pdf
3430

35-
test-session.pdf: content/test-session/chapter.tex
36-
cd build && $(LATEXCMD) test-session.tex
31+
.PHONY: help fast kactl clean veryclean
32+
33+
build:
34+
mkdir -p build/
35+
36+
test-session.pdf: content/test-session/test-session.tex content/test-session/chapter.tex | build
37+
$(LATEXCMD) content/test-session/test-session.tex
3738
cp build/test-session.pdf test-session.pdf

content/data-structures/HashMap.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Author: Simon Lindholm
2+
* Author: Simon Lindholm, chilli
33
* Date: 2018-07-23
44
* License: CC0
55
* Source: http://codeforces.com/blog/entry/60737
@@ -9,12 +9,19 @@
99
#pragma once
1010

1111
#include <bits/extc++.h> /** keep-include */
12-
__gnu_pbds::gp_hash_table<ll, int> h({},{},{},{}, {1 << 16});
12+
// To use most bits rather than just the lowest ones:
13+
struct chash {
14+
const uint64_t C = ll(2e18 * M_PI) + 71; // large odd number
15+
ll operator()(ll x) const { return __builtin_bswap64(x*C); }
16+
};
17+
__gnu_pbds::gp_hash_table<ll,int,chash> h({},{},{},{},{1<<16});
1318

1419
/** For CodeForces, or other places where hacking might be a problem:
20+
1521
const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
16-
struct chash {
17-
int operator()(ll x) const { return x ^ RANDOM; }
22+
struct chash { // To use most bits rather than just the lowest ones:
23+
const uint64_t C = ll(2e18 * M_PI) + 71; // large odd number
24+
ll operator()(ll x) const { return __builtin_bswap64((x^RANDOM)*C); }
1825
};
1926
__gnu_pbds::gp_hash_table<ll, int, chash> h({},{},{},{}, {1 << 16});
2027
*/

content/data-structures/RMQ.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct RMQ {
1919

2020
RMQ(const vector<T>& V) {
2121
int N = sz(V), on = 1, depth = 1;
22-
while (on < sz(V)) on *= 2, depth++;
22+
while (on < N) on *= 2, depth++;
2323
jmp.assign(depth, V);
2424
rep(i,0,depth-1) rep(j,0,N)
2525
jmp[i+1][j] = min(jmp[i][j],

content/geometry/ConvexHull.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Points on the edge of the hull between two other points are not considered part
1010
\end{minipage}
1111
\begin{minipage}{15mm}
1212
\vspace{-6mm}
13-
\includegraphics[width=\textwidth]{../content/geometry/ConvexHull}
13+
\includegraphics[width=\textwidth]{content/geometry/ConvexHull}
1414
\vspace{-6mm}
1515
\end{minipage}
1616
* Status: tested with Kattis problems convexhull

content/geometry/FastDelaunay.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct Quad {
2626
P F() { return r()->p; }
2727
Q r() { return rot->rot; }
2828
Q prev() { return rot->o->rot; }
29-
Q next() { return rot->r()->o->rot; }
29+
Q next() { return r()->prev(); }
3030
};
3131

3232
bool circ(P p, P a, P b, P c) { // is p in the circumcircle?
@@ -35,13 +35,11 @@ bool circ(P p, P a, P b, P c) { // is p in the circumcircle?
3535
return p.cross(a,b)*C + p.cross(b,c)*A + p.cross(c,a)*B > 0;
3636
}
3737
Q makeEdge(P orig, P dest) {
38-
Q q0 = new Quad{0,0,0,orig}, q1 = new Quad{0,0,0,arb},
39-
q2 = new Quad{0,0,0,dest}, q3 = new Quad{0,0,0,arb};
40-
q0->o = q0; q2->o = q2; // 0-0, 2-2
41-
q1->o = q3; q3->o = q1; // 1-3, 3-1
42-
q0->rot = q1; q1->rot = q2;
43-
q2->rot = q3; q3->rot = q0;
44-
return q0;
38+
Q q[] = {new Quad{0,0,0,orig}, new Quad{0,0,0,arb},
39+
new Quad{0,0,0,dest}, new Quad{0,0,0,arb}};
40+
rep(i,0,4)
41+
q[i]->o = q[-i & 3], q[i]->rot = q[(i+1) & 3];
42+
return *q;
4543
}
4644
void splice(Q a, Q b) {
4745
swap(a->o->rot->o, b->o->rot->o); swap(a->o, b->o);
@@ -66,9 +64,9 @@ pair<Q,Q> rec(const vector<P>& s) {
6664
#define H(e) e->F(), e->p
6765
#define valid(e) (e->F().cross(H(base)) > 0)
6866
Q A, B, ra, rb;
69-
int half = (sz(s) + 1) / 2;
70-
tie(ra, A) = rec({s.begin(), s.begin() + half});
71-
tie(B, rb) = rec({s.begin() + half, s.end()});
67+
int half = sz(s) / 2;
68+
tie(ra, A) = rec({all(s) - half});
69+
tie(B, rb) = rec({sz(s) - half + all(s)});
7270
while ((B->p.cross(H(A)) < 0 && (A = A->next())) ||
7371
(A->p.cross(H(B)) > 0 && (B = B->r()->o)));
7472
Q base = connect(B->r(), A);

content/geometry/Point.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
#pragma once
1111

12+
template <class T> int sgn(T x) { return (x > 0) - (x < 0); }
1213
template<class T>
1314
struct Point {
1415
typedef Point P;

content/geometry/PolygonCut.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
\end{minipage}
1010
\begin{minipage}{15mm}
1111
\vspace{-6mm}
12-
\includegraphics[width=\textwidth]{../content/geometry/PolygonCut}
12+
\includegraphics[width=\textwidth]{content/geometry/PolygonCut}
1313
\vspace{-6mm}
1414
\end{minipage}
1515
* Status: tested but not extensively

content/geometry/SegmentDistance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Returns the shortest distance between point p and the line segment from point s
99
\end{minipage}
1010
\begin{minipage}{15mm}
1111
\vspace{-10mm}
12-
\includegraphics[width=\textwidth]{../content/geometry/SegmentDistance}
12+
\includegraphics[width=\textwidth]{content/geometry/SegmentDistance}
1313
\end{minipage}
1414
* Status: tested
1515
* Usage:
Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,39 @@
11
/**
2-
* Author: Ulf Lundstrom
3-
* Date: 2009-03-21
2+
* Author: Victor Lecomte, chilli
3+
* Date: 2019-04-27
44
* License: CC0
5-
* Source:
5+
* Source: https://vlecomte.github.io/cp-geo.pdf
66
* Description:\\
77
\begin{minipage}{75mm}
8-
If a unique intersetion point between the line segments going from s1 to e1 and from s2 to e2 exists r1 is set to this point and 1 is returned.
9-
If no intersection point exists 0 is returned and if infinitely many exists 2 is returned and r1 and r2 are set to the two ends of the common line.
10-
The wrong position will be returned if P is Point<int> and the intersection point does not have integer coordinates.
8+
If a unique intersection point between the line segments going from s1 to e1 and from s2 to e2 exists then it is returned.
9+
If no intersection point exists an empty vector is returned. If infinitely many exist a vector with 2 elements is returned, containing the endpoints of the common line segment.
10+
The wrong position will be returned if P is Point<ll> and the intersection point does not have integer coordinates.
1111
Products of three coordinates are used in intermediate steps so watch out for overflow if using int or long long.
12-
Use segmentIntersectionQ to get just a true/false answer.
1312
\end{minipage}
1413
\begin{minipage}{15mm}
15-
\includegraphics[width=\textwidth]{../content/geometry/SegmentIntersection}
14+
\includegraphics[width=\textwidth]{content/geometry/SegmentIntersection}
1615
\end{minipage}
17-
* Status: Well tested with unitTest and with Kattis problem intersection.
16+
* Status: Well tested with fuzz-test and with Kattis problem intersection.
1817
* Usage:
19-
* Point<double> intersection, dummy;
20-
* if (segmentIntersection(s1,e1,s2,e2,intersection,dummy)==1)
21-
* cout << "segments intersect at " << intersection << endl;
18+
* vector<P> inter = segInter(s1,e1,s2,e2);
19+
* if (sz(inter)==1)
20+
* cout << "segments intersect at " << inter[0] << endl;
2221
*/
2322
#pragma once
2423

2524
#include "Point.h"
25+
#include "onSegment.h"
2626

27-
template<class P>
28-
int segmentIntersection(const P& s1, const P& e1,
29-
const P& s2, const P& e2, P& r1, P& r2) {
30-
if (e1==s1) {
31-
if (e2==s2) {
32-
if (e1==e2) { r1 = e1; return 1; } //all equal
33-
else return 0; //different point segments
34-
} else return segmentIntersection(s2,e2,s1,e1,r1,r2);//swap
35-
}
36-
//segment directions and separation
37-
P v1 = e1-s1, v2 = e2-s2, d = s2-s1;
38-
auto a = v1.cross(v2), a1 = v1.cross(d), a2 = v2.cross(d);
39-
if (a == 0) { //if parallel
40-
auto b1=s1.dot(v1), c1=e1.dot(v1),
41-
b2=s2.dot(v1), c2=e2.dot(v1);
42-
if (a1 || a2 || max(b1,min(b2,c2))>min(c1,max(b2,c2)))
43-
return 0;
44-
r1 = min(b2,c2)<b1 ? s1 : (b2<c2 ? s2 : e2);
45-
r2 = max(b2,c2)>c1 ? e1 : (b2>c2 ? s2 : e2);
46-
return 2-(r1==r2);
47-
}
48-
if (a < 0) { a = -a; a1 = -a1; a2 = -a2; }
49-
if (0<a1 || a<-a1 || 0<a2 || a<-a2)
50-
return 0;
51-
r1 = s1-v1*a2/a;
52-
return 1;
27+
template<class P> vector<P> segInter(P a, P b, P c, P d) {
28+
auto oa = c.cross(d, a), ob = c.cross(d, b),
29+
oc = a.cross(b, c), od = a.cross(b, d);
30+
// Checks if intersection is single non-endpoint point.
31+
if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn(od) < 0)
32+
return {(a * ob - b * oa) / (ob - oa)};
33+
set<P> s;
34+
if (onSegment(c, d, a)) s.insert(a);
35+
if (onSegment(c, d, b)) s.insert(b);
36+
if (onSegment(a, b, c)) s.insert(c);
37+
if (onSegment(a, b, d)) s.insert(d);
38+
return {all(s)};
5339
}

content/geometry/SegmentIntersectionQ.h

Lines changed: 0 additions & 29 deletions
This file was deleted.

content/geometry/chapter.tex

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,13 @@ \section{Geometric primitives}
66
\kactlimport{SegmentDistance.h}
77
\columnbreak
88
\kactlimport{SegmentIntersection.h}
9-
\kactlimport{SegmentIntersectionQ.h}
10-
\columnbreak
119
\kactlimport{lineIntersection.h}
1210
\kactlimport{sideOf.h}
1311
\kactlimport{onSegment.h}
1412
\kactlimport{linearTransformation.h}
1513
\kactlimport{Angle.h}
1614

17-
\section{Circles}
15+
\section{Circles}
1816
\kactlimport{CircleIntersection.h}
1917
\kactlimport{circleTangents.h}
2018
\kactlimport{circumcircle.h}

content/geometry/circleTangents.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Returns a pair of the two points on the circle with radius r centered around c whos tangent lines intersect p. If p lies within the circle NaN-points are returned. P is intended to be Point<double>. The first point is the one to the right as seen from the p towards c.
99
\end{minipage}
1010
\begin{minipage}{15mm}
11-
\includegraphics[width=\textwidth]{../content/geometry/circleTangents}
11+
\includegraphics[width=\textwidth]{content/geometry/circleTangents}
1212
\end{minipage}
1313
* Status: tested
1414
* Usage:

content/geometry/circumcircle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ The circumcirle of a triangle is the circle intersecting all three vertices. ccR
99
\end{minipage}
1010
\begin{minipage}{15mm}
1111
\vspace{-2mm}
12-
\includegraphics[width=\textwidth]{../content/geometry/circumcircle}
12+
\includegraphics[width=\textwidth]{content/geometry/circumcircle}
1313
\end{minipage}
1414
* Status: tested
1515
*/

content/geometry/lineDistance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Returns the signed distance between point p and the line containing points a and b. Positive value on left side and negative on right as seen from a towards b. a==b gives nan. P is supposed to be Point<T> or Point3D<T> where T is e.g. double or long long. It uses products in intermediate steps so watch out for overflow if using int or long long. Using Point3D will always give a non-negative distance.
99
\end{minipage}
1010
\begin{minipage}{15mm}
11-
\includegraphics[width=\textwidth]{../content/geometry/lineDistance}
11+
\includegraphics[width=\textwidth]{content/geometry/lineDistance}
1212
\end{minipage}
1313
* Status: tested
1414
*/

content/geometry/lineIntersection.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
* Source:
66
* Description:\\
77
\begin{minipage}{75mm}
8-
If a unique intersetion point of the lines going through s1,e1 and s2,e2 exists r is set to this point and 1 is returned. If no intersection point exists 0 is returned and if infinitely many exists -1 is returned. If s1==e1 or s2==e2 -1 is returned. The wrong position will be returned if P is Point<int> and the intersection point does not have integer coordinates. Products of three coordinates are used in intermediate steps so watch out for overflow if using int or long long.
8+
If a unique intersection point of the lines going through s1,e1 and s2,e2 exists r is set to this point and 1 is returned. If no intersection point exists 0 is returned and if infinitely many exists -1 is returned. If s1==e1 or s2==e2 -1 is returned. The wrong position will be returned if P is Point<ll> and the intersection point does not have integer coordinates. Products of three coordinates are used in intermediate steps so watch out for overflow if using int or long long.
99
\end{minipage}
1010
\begin{minipage}{15mm}
11-
\includegraphics[width=\textwidth]{../content/geometry/lineIntersection}
11+
\includegraphics[width=\textwidth]{content/geometry/lineIntersection}
1212
\end{minipage}
1313
* Status: tested
1414
* Usage:
@@ -23,9 +23,9 @@ If a unique intersetion point of the lines going through s1,e1 and s2,e2 exists
2323
template<class P>
2424
int lineIntersection(const P& s1, const P& e1, const P& s2,
2525
const P& e2, P& r) {
26-
if ((e1-s1).cross(e2-s2)) { //if not parallell
27-
r = s2-(e2-s2)*(e1-s1).cross(s2-s1)/(e1-s1).cross(e2-s2);
26+
if ((e1-s1).cross(e2-s2)) { // if not parallel
27+
r = s2-(e2-s2)*s1.cross(e1, s2)/(e1-s1).cross(e2-s2);
2828
return 1;
2929
} else
30-
return -((e1-s1).cross(s2-s1)==0 || s2==e2);
30+
return -(s1.cross(e1, s2)==0 || s2==e2);
3131
}

content/geometry/linearTransformation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
\end{minipage}
1010
\begin{minipage}{15mm}
1111
\vspace{-8mm}
12-
\includegraphics[width=\textwidth]{../content/geometry/linearTransformation}
12+
\includegraphics[width=\textwidth]{content/geometry/linearTransformation}
1313
\vspace{-2mm}
1414
\end{minipage}
1515
* Status: not tested

content/geometry/onSegment.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
/**
2-
* Author: Ulf Lundstrom
3-
* Date: 2009-04-09
2+
* Author: Victor Lecomte, chilli
3+
* Date: 2019-04-26
44
* License: CC0
5-
* Source: Basic geometry
6-
* Description: Returns true iff p lies on the line segment from s to e. Intended for use with e.g. Point<long long> where overflow is an issue. Use (segDist(s,e,p)<=epsilon) instead when using Point<double>.
5+
* Source: https://vlecomte.github.io/cp-geo.pdf
6+
* Description: Returns true iff p lies on the line segment from s to e. Intended for use with e.g. Point<ll> where overflow is an issue. Use \texttt{(segDist(s,e,p)<=epsilon)} instead when using Point<double>.
77
* Status:
88
*/
99
#pragma once
1010

1111
#include "Point.h"
1212

13-
template<class P>
14-
bool onSegment(const P& s, const P& e, const P& p) {
15-
P ds = p-s, de = p-e;
16-
return ds.cross(de) == 0 && ds.dot(de) <= 0;
13+
template<class P> bool onSegment(P s, P e, P p) {
14+
return p.cross(s, e) == 0 && (s - p).dot(e - p) <= 0;
1715
}

0 commit comments

Comments
 (0)