forked from bicsi/code_snippets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamic_hull.cpp
55 lines (41 loc) · 1.23 KB
/
dynamic_hull.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
template<typename T>
struct DynamicHull {
typedef pair<T, T> Point;
#define x first
#define y second
#define det(A, B, C) 1LL * (B.x - A.x) * (C.y - A.y) - 1LL * (B.y - A.y) * (C.x - A.x)
set<Point> Up, Dw;
set<Point>::iterator aux, cur, pred, succ;
static bool bad(set<Point> &Set, set<Point>::iterator it) {
if(it == Set.begin()) return false;
if(++it == Set.end()) return false;
auto C = *it--, B = *it--, A = *it;
return det(A, B, C) <= 0;
}
void chk_succ(set<Point> &Set) {
succ = cur; succ++;
if(succ == Set.end()) return;
while(bad(Set, succ))
Set.erase(aux = succ++);
}
void chk_pred(set<Point> &Set) {
if(cur == Set.begin()) return;
pred = cur; pred--;
while(bad(Set, pred))
Set.erase(aux = pred--);
}
void ins(Point P, set<Point> &Set) {
cur = Set.insert(P).first;
if(Set.size() <= 2) return;
if(bad(Set, cur)) { Set.erase(cur); return; }
chk_pred(Set);
chk_succ(Set);
}
void insertPoint(T a, T b) {
ins(Point(a, b), Up);
ins(Point(-a, -b), Dw);
}
#undef first
#undef second
#undef det
};