Skip to the content.

:warning: library/algebra/monoid/RollingHash.hpp

Depends on

Code

template <typename CHAR = char> struct MonoidRollingHash {
    using u64 = std::uint64_t;
    using u128 = unsigned __int128;
    using value_type = std::pair<u64, u64>;
    using X = value_type;
    static constexpr u64 mod = (1ULL << 61) - 1, base = 20120620;
    static constexpr u64 mul(u64 a, u64 b) {
        u128 u = static_cast<u128>(a) * b;
        a = (u >> 61) + u & mod;
        return a >= mod ? a - mod : a;
    }

    static constexpr X op(const X &x, const X &y) {
        const auto &[vx, px] = x;
        const auto &[vy, py] = y;
        return X((mul(vx, py) + vy) & mod, mul(px, py));
    }
    static constexpr void Rchop(X &x, const X &y) { x = op(x, y); }
    static constexpr void Lchop(const X &x, X &y) { y = op(x, y); }
    static constexpr X unit() { return X(0, 1); }
    static constexpr bool commute = false;

    static constexpr X to_X(const CHAR &c) { return X(c, base); }

    template <typename STRING>
    static constexpr std::vector<X> to_vec(const STRING &s) {
        std::vector<X> ret(s.size());
        for (int i = 0; i < s.size(); i++)
            ret[i] = to_X(s[i]);
        return ret;
    }
};
#line 1 "library/algebra/monoid/RollingHash.hpp"
template <typename CHAR = char> struct MonoidRollingHash {
    using u64 = std::uint64_t;
    using u128 = unsigned __int128;
    using value_type = std::pair<u64, u64>;
    using X = value_type;
    static constexpr u64 mod = (1ULL << 61) - 1, base = 20120620;
    static constexpr u64 mul(u64 a, u64 b) {
        u128 u = static_cast<u128>(a) * b;
        a = (u >> 61) + u & mod;
        return a >= mod ? a - mod : a;
    }

    static constexpr X op(const X &x, const X &y) {
        const auto &[vx, px] = x;
        const auto &[vy, py] = y;
        return X((mul(vx, py) + vy) & mod, mul(px, py));
    }
    static constexpr void Rchop(X &x, const X &y) { x = op(x, y); }
    static constexpr void Lchop(const X &x, X &y) { y = op(x, y); }
    static constexpr X unit() { return X(0, 1); }
    static constexpr bool commute = false;

    static constexpr X to_X(const CHAR &c) { return X(c, base); }

    template <typename STRING>
    static constexpr std::vector<X> to_vec(const STRING &s) {
        std::vector<X> ret(s.size());
        for (int i = 0; i < s.size(); i++)
            ret[i] = to_X(s[i]);
        return ret;
    }
};
Back to top page