library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub tko919/library

:warning: Geometry(integer Coordinates)
(Geometry/intCoord.hpp)

Code

#pragma once

struct Point {
    ll X, Y;
    Point() : X(0), Y(0) {}
    Point(ll _X, ll _Y) : X(_X), Y(_Y) {}
    int pos() const {
        if (Y < 0)
            return -1;
        if (Y == 0 and X >= 0)
            return 0;
        return 1;
    }
    Point &operator+=(const Point &p) {
        X += p.X;
        Y += p.Y;
        return *this;
    }
    Point &operator-=(const Point &p) {
        X -= p.X;
        Y -= p.Y;
        return *this;
    }
    Point &operator*=(const ll &t) {
        X *= t, Y *= t;
        return *this;
    }
    Point &operator*=(const Point &p) {
        ll NX = X * p.X - Y * p.Y, NY = X * p.Y + Y * p.X;
        X = NX, Y = NY;
        return *this;
    }
    Point operator+(const Point &p) const {
        return Point(*this) += p;
    }
    Point operator-(const Point &p) const {
        return Point(*this) -= p;
    }
    Point operator*(const ll &p) const {
        return Point(*this) *= p;
    }
    Point operator*(const Point &p) const {
        return Point(*this) *= p;
    }
    Point operator-() const {
        return Point(-X, -Y);
    }
    bool operator==(const Point &p) const {
        return X == p.X && Y == p.Y;
    }
    bool operator!=(const Point &p) const {
        return X != p.X || Y != p.Y;
    }
    bool operator<(const Point &p) const {
        return X == p.X ? Y < p.Y : X < p.X;
    }
};
struct Line {
    Point a, b;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b) {}
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
using Poly = vector<Point>;

ll dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
ll cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
ll norm(const Point &a) {
    return a.X * a.X + a.Y * a.Y;
}
bool cmp(const Point &a, const Point &b) {
    if (a.pos() != b.pos())
        return a.pos() < b.pos();
    return a.Y * b.X < a.X * b.Y;
}

int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    ll C = cross(b, c);
    if (C > 0)
        return 1; // ccw
    if (C < 0)
        return -1; // cw
    if (dot(b, c) < 0)
        return 2; // c,a,b
    if (dot(b, b) < dot(c, c))
        return -2; // a,b,c
    return 0;      // a,c,b
}

bool isOrthogonal(const Line &a, const Line &b) {
    return dot(a.b - a.a, b.b - b.a) == 0;
}
bool isParallel(const Line &a, const Line &b) {
    return cross(a.b - a.a, b.b - b.a) == 0;
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}

int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain
    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y <= 0 and q.Y > 0 and cross(p, q) > 0)
            res ^= 1;
        if (cross(p, q) == 0 and dot(p, q) <= 0)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (p.Y == q.Y ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    if (n <= 2)
        return a;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) <= 0)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) <= 0)
            k--;
    }
    res.resize(k - 1);
    return res;
}

/**
 * @brief Geometry(integer Coordinates)
 */
#line 2 "Geometry/intCoord.hpp"

struct Point {
    ll X, Y;
    Point() : X(0), Y(0) {}
    Point(ll _X, ll _Y) : X(_X), Y(_Y) {}
    int pos() const {
        if (Y < 0)
            return -1;
        if (Y == 0 and X >= 0)
            return 0;
        return 1;
    }
    Point &operator+=(const Point &p) {
        X += p.X;
        Y += p.Y;
        return *this;
    }
    Point &operator-=(const Point &p) {
        X -= p.X;
        Y -= p.Y;
        return *this;
    }
    Point &operator*=(const ll &t) {
        X *= t, Y *= t;
        return *this;
    }
    Point &operator*=(const Point &p) {
        ll NX = X * p.X - Y * p.Y, NY = X * p.Y + Y * p.X;
        X = NX, Y = NY;
        return *this;
    }
    Point operator+(const Point &p) const {
        return Point(*this) += p;
    }
    Point operator-(const Point &p) const {
        return Point(*this) -= p;
    }
    Point operator*(const ll &p) const {
        return Point(*this) *= p;
    }
    Point operator*(const Point &p) const {
        return Point(*this) *= p;
    }
    Point operator-() const {
        return Point(-X, -Y);
    }
    bool operator==(const Point &p) const {
        return X == p.X && Y == p.Y;
    }
    bool operator!=(const Point &p) const {
        return X != p.X || Y != p.Y;
    }
    bool operator<(const Point &p) const {
        return X == p.X ? Y < p.Y : X < p.X;
    }
};
struct Line {
    Point a, b;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b) {}
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
using Poly = vector<Point>;

ll dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
ll cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
ll norm(const Point &a) {
    return a.X * a.X + a.Y * a.Y;
}
bool cmp(const Point &a, const Point &b) {
    if (a.pos() != b.pos())
        return a.pos() < b.pos();
    return a.Y * b.X < a.X * b.Y;
}

int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    ll C = cross(b, c);
    if (C > 0)
        return 1; // ccw
    if (C < 0)
        return -1; // cw
    if (dot(b, c) < 0)
        return 2; // c,a,b
    if (dot(b, b) < dot(c, c))
        return -2; // a,b,c
    return 0;      // a,c,b
}

bool isOrthogonal(const Line &a, const Line &b) {
    return dot(a.b - a.a, b.b - b.a) == 0;
}
bool isParallel(const Line &a, const Line &b) {
    return cross(a.b - a.a, b.b - b.a) == 0;
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}

int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain
    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y <= 0 and q.Y > 0 and cross(p, q) > 0)
            res ^= 1;
        if (cross(p, q) == 0 and dot(p, q) <= 0)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (p.Y == q.Y ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    if (n <= 2)
        return a;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) <= 0)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) <= 0)
            k--;
    }
    res.resize(k - 1);
    return res;
}

/**
 * @brief Geometry(integer Coordinates)
 */
Back to top page