summaryrefslogtreecommitdiff
path: root/content/datastructures/dynamicConvexHull.cpp
diff options
context:
space:
mode:
authorGloria Mundi <gloria@gloria-mundi.eu>2024-11-16 01:24:14 +0100
committerGloria Mundi <gloria@gloria-mundi.eu>2024-11-16 01:24:14 +0100
commit98567ec798aa8ca2cfbcb85c774dd470f30e30d4 (patch)
tree5113d5cc24d1ad5f93810b6442ce584a36950dc8 /content/datastructures/dynamicConvexHull.cpp
parentad3856a6b766087df0036de0b556f4700a6498c9 (diff)
parent8d11c6c8213f46f0fa19826917c255edd5d43cb1 (diff)
mzuenni tests
Diffstat (limited to 'content/datastructures/dynamicConvexHull.cpp')
-rw-r--r--content/datastructures/dynamicConvexHull.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/content/datastructures/dynamicConvexHull.cpp b/content/datastructures/dynamicConvexHull.cpp
new file mode 100644
index 0000000..2bd67a6
--- /dev/null
+++ b/content/datastructures/dynamicConvexHull.cpp
@@ -0,0 +1,34 @@
+struct Line {
+ mutable ll m, b, p;
+ bool operator<(const Line& o) const {return m < o.m;}
+ bool operator<(ll x) const {return p < x;}
+};
+
+struct HullDynamic : multiset<Line, less<>> {
+ // (for doubles, use inf = 1/.0, div(a,b) = a/b)
+ ll div(ll a, ll b) {return a / b - ((a ^ b) < 0 && a % b);}
+
+ bool isect(iterator x, iterator y) {
+ if (y == end()) {x->p = INF; return false;}
+ if (x->m == y->m) x->p = x->b > y->b ? INF : -INF;
+ else x->p = div(y->b - x->b, x->m - y->m);
+ return x->p >= y->p;
+ }
+
+ void add(ll m, ll b) {
+ auto x = insert({m, b, 0});
+ while (isect(x, next(x))) erase(next(x));
+ if (x != begin()) {
+ --x;
+ while (isect(x, next(x))) erase(next(x));
+ }
+ while (x != begin() && prev(x)->p >= x->p) {
+ --x;
+ isect(x, erase(next(x)));
+ }}
+
+ ll query(ll x) {
+ auto l = *lower_bound(x);
+ return l.m * x + l.b;
+ }
+};