This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub habara-k/ac-library
#include "atcoder/rollinghash.hpp"
#ifndef ATCODER_ROLLINGHASH_HPP #define ATCODER_ROLLINGHASH_HPP 1 #include <random> namespace atcoder { struct RollingHash { using u128 = __uint128_t; using u64 = uint64_t; template<typename S> explicit RollingHash(const S &s, int seed=0) { std::mt19937 random(seed); std::uniform_int_distribution<u64> dist(2, MOD-2); u64 base = dist(random); int n = int(s.size()); hash.assign(n+1, 0); pow.assign(n+1, 1); for (int i = 0; i < n; ++i) { hash[i+1] = mul(hash[i], base) + s[i]; if (hash[i+1] >= MOD) hash[i+1] -= MOD; pow[i+1] = mul(pow[i], base); } } u64 get(int l, int r) const { u64 ret = hash[r] + MOD - mul(hash[l], pow[r-l]); return ret >= MOD ? ret - MOD : ret; } private: std::vector<u64> hash, pow; static const u64 MOD = (1ull << 61) - 1; static u64 mul(u128 a, u128 b) { u128 t = a * b; t = (t >> 61) + (t & MOD); return u64(t >= MOD ? t - MOD : t); } }; } // namespace atcoder #endif // ATCODER_ROLLINGHASH_HPP
#line 1 "atcoder/rollinghash.hpp" #include <random> namespace atcoder { struct RollingHash { using u128 = __uint128_t; using u64 = uint64_t; template<typename S> explicit RollingHash(const S &s, int seed=0) { std::mt19937 random(seed); std::uniform_int_distribution<u64> dist(2, MOD-2); u64 base = dist(random); int n = int(s.size()); hash.assign(n+1, 0); pow.assign(n+1, 1); for (int i = 0; i < n; ++i) { hash[i+1] = mul(hash[i], base) + s[i]; if (hash[i+1] >= MOD) hash[i+1] -= MOD; pow[i+1] = mul(pow[i], base); } } u64 get(int l, int r) const { u64 ret = hash[r] + MOD - mul(hash[l], pow[r-l]); return ret >= MOD ? ret - MOD : ret; } private: std::vector<u64> hash, pow; static const u64 MOD = (1ull << 61) - 1; static u64 mul(u128 a, u128 b) { u128 t = a * b; t = (t >> 61) + (t & MOD); return u64(t >= MOD ? t - MOD : t); } }; } // namespace atcoder