cp-library-cpp

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

View the Project on GitHub suisen-cp/cp-library-cpp

:warning: Affine Clamp
(library/algebra/monoid/affine_clamp.hpp)

Affine Clamp

Depends on

Code

#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
Back to top page