This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub suisen-cp/cp-library-cpp
#include "library/algebra/monoid/affine_clamp.hpp"
#ifndef SUISEN_AFFINE_CLAMP #define SUISEN_AFFINE_CLAMP #include <algorithm> #include <limits> #include <type_traits> #include "library/algebra/monoid/affine.hpp" namespace suisen { template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr> struct AffineClamp : public Affine<T> { static constexpr T neg_inf = std::numeric_limits<T>::min(); static constexpr T pos_inf = std::numeric_limits<T>::max(); T l, r; AffineClamp(const T &a = 1, const T &b = 0, const T &l = neg_inf, T r = pos_inf) : Affine<T>(a, b), l(l), r(r) {} AffineClamp(const Affine<T> &f, const T &l = neg_inf, const T &r = pos_inf) : Affine<T>(f), l(l), r(r) {} static AffineClamp<T> id() { return AffineClamp<T>{}; } static AffineClamp<T> compose(const AffineClamp<T>& f, const AffineClamp<T>& g) { AffineClamp<T> h{ Affine<T>::compose(f, g), f.affine_clamp(g.l), f.affine_clamp(g.r) }; if (h.l > h.r) std::swap(h.l, h.r); return h; } AffineClamp<T> compose(const AffineClamp<T>& g) const { return AffineClamp<T>::compose(*this, g); } T affine_clamp(const T &x) const { return std::clamp<__int128_t>(this->template affine<__int128_t>(x), l, r); } T operator()(const T &x) const { return affine_clamp(x); } template <typename U = T, typename V = T, typename W = T, typename X = T> operator std::tuple<U, V, W, X>() { return { this->a, this->b, l, r }; } friend std::istream& operator<<(std::istream& in, AffineClamp<T>& f) { return in >> f.a >> f.b >> f.l >> f.r; } friend std::ostream& operator>>(std::ostream& out, const AffineClamp<T>& f) { return out << f.a << ' ' << f.b << ' ' << f.l << ' ' << f.r; } }; } // namespace suisen #endif // SUISEN_AFFINE_CLAMP
#line 1 "library/algebra/monoid/affine_clamp.hpp" #include <algorithm> #include <limits> #include <type_traits> #line 1 "library/algebra/monoid/affine.hpp" #include <iostream> #include <utility> namespace suisen { template <typename T> struct Affine { T a, b; Affine(const T &a = 1, const T &b = 0) : a(a), b(b) {} static Affine<T> id() { return Affine<T>{}; } static Affine<T> compose(const Affine<T>& f, const Affine<T>& g) { return f.compose(g); } Affine<T> compose(const Affine<T>& g) const { return { a * g.a, affine(g.b) }; } template <typename U = T> U affine(const T &x) const { return U(a) * x + b; } T operator()(const T &x) const { return affine<T>(x); } Affine<T> operator+() const { return *this; } Affine<T> operator-() const { return { -a, -b }; } Affine<T>& operator++() { ++b; return *this; } Affine<T>& operator--() { --b; return *this; } Affine<T> operator++(int) { Affine<T> f(*this); ++(*this); return f; } Affine<T> operator--(int) { Affine<T> f(*this); --(*this); return f; } Affine<T>& operator+=(const T& c) { b += c; return *this; } Affine<T>& operator-=(const T& c) { b -= c; return *this; } friend Affine<T> operator+(Affine<T> f, const T &c) { f += c; return f; } friend Affine<T> operator-(Affine<T> f, const T &c) { f -= c; return f; } Affine<T>& operator+=(const Affine<T> &g) { a += g.a, b += g.b; return *this; } Affine<T>& operator-=(const Affine<T> &g) { a -= g.a, b -= g.b; return *this; } friend Affine<T> operator+(Affine<T> f, const Affine<T> &g) { f += g; return f; } friend Affine<T> operator-(Affine<T> f, const Affine<T> &g) { f -= g; return f; } friend bool operator==(const Affine<T> &f, const Affine<T> &g) { return f.a == g.a and f.b == g.b; } friend bool operator!=(const Affine<T> &f, const Affine<T> &g) { return not (f == g); } friend bool operator< (const Affine<T> &f, const Affine<T> &g) { return f.a < g.a or (f.a == g.a and f.b < g.b); } friend bool operator<=(const Affine<T> &f, const Affine<T> &g) { return not (g < f); } friend bool operator> (const Affine<T> &f, const Affine<T> &g) { return g < f; } friend bool operator>=(const Affine<T> &f, const Affine<T> &g) { return not (f < g); } template <typename U = T, typename V = T> operator std::pair<U, V>() { return std::pair<U, V>{ a, b }; } template <typename U = T, typename V = T> operator std::tuple<U, V>() { return std::tuple<U, V>{ a, b }; } friend std::istream& operator<<(std::istream& in, Affine<T> &f) { return in >> f.a >> f.b; } friend std::ostream& operator>>(std::ostream& out, const Affine<T> &f) { return out << f.a << ' ' << f.b; } }; } // namespace suisen #line 9 "library/algebra/monoid/affine_clamp.hpp" namespace suisen { template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr> struct AffineClamp : public Affine<T> { static constexpr T neg_inf = std::numeric_limits<T>::min(); static constexpr T pos_inf = std::numeric_limits<T>::max(); T l, r; AffineClamp(const T &a = 1, const T &b = 0, const T &l = neg_inf, T r = pos_inf) : Affine<T>(a, b), l(l), r(r) {} AffineClamp(const Affine<T> &f, const T &l = neg_inf, const T &r = pos_inf) : Affine<T>(f), l(l), r(r) {} static AffineClamp<T> id() { return AffineClamp<T>{}; } static AffineClamp<T> compose(const AffineClamp<T>& f, const AffineClamp<T>& g) { AffineClamp<T> h{ Affine<T>::compose(f, g), f.affine_clamp(g.l), f.affine_clamp(g.r) }; if (h.l > h.r) std::swap(h.l, h.r); return h; } AffineClamp<T> compose(const AffineClamp<T>& g) const { return AffineClamp<T>::compose(*this, g); } T affine_clamp(const T &x) const { return std::clamp<__int128_t>(this->template affine<__int128_t>(x), l, r); } T operator()(const T &x) const { return affine_clamp(x); } template <typename U = T, typename V = T, typename W = T, typename X = T> operator std::tuple<U, V, W, X>() { return { this->a, this->b, l, r }; } friend std::istream& operator<<(std::istream& in, AffineClamp<T>& f) { return in >> f.a >> f.b >> f.l >> f.r; } friend std::ostream& operator>>(std::ostream& out, const AffineClamp<T>& f) { return out << f.a << ' ' << f.b << ' ' << f.l << ' ' << f.r; } }; } // namespace suisen