src/jiangly/math/11A-Convex-Hull.hpp
Code
/** 静态凸包(with. Point,旧版)
* 2023-04-09: https://cf.dianhsu.com/gym/104288/submission/201412835
**/
struct Point {
i64 x;
i64 y;
Point(i64 x = 0, i64 y = 0) : x(x), y(y) {}
};
bool operator==(const Point &a, const Point &b) {
return a.x == b.x && a.y == b.y;
}
Point operator+(const Point &a, const Point &b) {
return Point(a.x + b.x, a.y + b.y);
}
Point operator-(const Point &a, const Point &b) {
return Point(a.x - b.x, a.y - b.y);
}
i64 dot(const Point &a, const Point &b) {
return a.x * b.x + a.y * b.y;
}
i64 cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
}
void norm(std::vector<Point> &h) {
int i = 0;
for (int j = 0; j < int(h.size()); j++) {
if (h[j].y < h[i].y || (h[j].y == h[i].y && h[j].x < h[i].x)) {
i = j;
}
}
std::rotate(h.begin(), h.begin() + i, h.end());
}
int sgn(const Point &a) {
return a.y > 0 || (a.y == 0 && a.x > 0) ? 0 : 1;
}
std::vector<Point> getHull(std::vector<Point> p) {
std::vector<Point> h, l;
std::sort(p.begin(), p.end(), [&](auto a, auto b) {
if (a.x != b.x) {
return a.x < b.x;
} else {
return a.y < b.y;
}
});
p.erase(std::unique(p.begin(), p.end()), p.end());
if (p.size() <= 1) {
return p;
}
for (auto a : p) {
while (h.size() > 1 && cross(a - h.back(), a - h[h.size() - 2]) <= 0) {
h.pop_back();
}
while (l.size() > 1 && cross(a - l.back(), a - l[l.size() - 2]) >= 0) {
l.pop_back();
}
l.push_back(a);
h.push_back(a);
}
l.pop_back();
std::reverse(h.begin(), h.end());
h.pop_back();
l.insert(l.end(), h.begin(), h.end());
return l;
}
#line 1 "src/jiangly/math/11A-Convex-Hull.hpp"
/** 静态凸包(with. Point,旧版)
* 2023-04-09: https://cf.dianhsu.com/gym/104288/submission/201412835
**/
struct Point {
i64 x;
i64 y;
Point(i64 x = 0, i64 y = 0) : x(x), y(y) {}
};
bool operator==(const Point &a, const Point &b) {
return a.x == b.x && a.y == b.y;
}
Point operator+(const Point &a, const Point &b) {
return Point(a.x + b.x, a.y + b.y);
}
Point operator-(const Point &a, const Point &b) {
return Point(a.x - b.x, a.y - b.y);
}
i64 dot(const Point &a, const Point &b) {
return a.x * b.x + a.y * b.y;
}
i64 cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
}
void norm(std::vector<Point> &h) {
int i = 0;
for (int j = 0; j < int(h.size()); j++) {
if (h[j].y < h[i].y || (h[j].y == h[i].y && h[j].x < h[i].x)) {
i = j;
}
}
std::rotate(h.begin(), h.begin() + i, h.end());
}
int sgn(const Point &a) {
return a.y > 0 || (a.y == 0 && a.x > 0) ? 0 : 1;
}
std::vector<Point> getHull(std::vector<Point> p) {
std::vector<Point> h, l;
std::sort(p.begin(), p.end(), [&](auto a, auto b) {
if (a.x != b.x) {
return a.x < b.x;
} else {
return a.y < b.y;
}
});
p.erase(std::unique(p.begin(), p.end()), p.end());
if (p.size() <= 1) {
return p;
}
for (auto a : p) {
while (h.size() > 1 && cross(a - h.back(), a - h[h.size() - 2]) <= 0) {
h.pop_back();
}
while (l.size() > 1 && cross(a - l.back(), a - l[l.size() - 2]) >= 0) {
l.pop_back();
}
l.push_back(a);
h.push_back(a);
}
l.pop_back();
std::reverse(h.begin(), h.end());
h.pop_back();
l.insert(l.end(), h.begin(), h.end());
return l;
}
Back to top page