#pragma once #include #include typedef long long ll; typedef unsigned long long ull; template struct Coord { T x, y; Coord() : Coord(0, 0) {} Coord(const T x, const T y) { this->x = x; this->y = y; } static inline const std::array, 4> units() { return { Coord(0, 1), Coord(1, 0), Coord(0, -1), Coord(-1, 0), }; } Coord operator-() { return {-this->x, -this->y}; } Coord &operator+=(const Coord &other) { x += other.x; y += other.y; return *this; } Coord &operator-=(const Coord &other) { x -= other.x; y -= other.y; return *this; } Coord &operator*=(const T other) { x *= other; y *= other; return *this; } Coord &operator/=(const T other) { x /= other; y /= other; return *this; } }; template Coord operator+(const Coord &lhs, const Coord &rhs) { Coord result = lhs; result += rhs; return result; } template Coord operator-(const Coord &lhs, const Coord &rhs) { Coord result = lhs; result -= rhs; return result; } template Coord operator*(const Coord &lhs, const T rhs) { Coord result = lhs; result *= rhs; return result; } template Coord operator/(const Coord &lhs, const T rhs) { Coord result = lhs; result /= rhs; return result; } template inline bool operator==(const Coord &lhs, const Coord &rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } template <> struct std::hash> { std::size_t operator()(const Coord &c) const noexcept { return (c.x << (sizeof(std::size_t) / 2)) - c.x + c.y; } }; template <> struct std::hash> { std::size_t operator()(const Coord &c) const noexcept { return (c.x << (sizeof(std::size_t) / 2)) - c.x + c.y; } }; typedef Coord icoord; typedef Coord ullcoord;