Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Rolling hash algorithm implemented as a monoid, typically stored in a segment tree. The type parameters \(b\) and \(p\) represent the B-adic base and the modulus, respectively.
Combining RollingHash
with SegTree
enables \(O(\log |s|)\) string slice creation and
\(O(1)\) slice comparison.
Since: 1.1.0.0
Synopsis
- data RollingHash b p = RollingHash {
- hashRH :: !Int
- nextDigitRH :: !Int
- new :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p
- unsafeNew :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p
Rolling hash
data RollingHash b p Source #
Rolling hash algorithm implemented as a monoid, typically stored in a segment tree. The type parameters \(b\) and \(p\) represent the B-adic base and the modulus, respectively.
Combining RollingHash
with SegTree
enables \(O(\log |s|)\) string slice creation and
\(O(1)\) slice comparison.
Example
It's convenient to define a type alias of RollingHash
:
>>>
import AtCoder.Extra.Monoid.RollingHash qualified as RH
>>>
import AtCoder.SegTree qualified as ST
>>>
import Data.Char (ord)
>>>
import Data.Semigroup (Dual (..))
>>>
type RH = RH.RollingHash 100 998244353
Let's test whether "abcba" is a palindrome:
>>>
seg <- ST.build @_ @RH . VU.map (RH.unsafeNew . ord) $ VU.fromList "abcba"
>>>
seg' <- ST.build @_ @(Dual RH) . VU.map (Dual . RH.unsafeNew . ord) $ VU.fromList "abcba"
>>>
hash1 <- ST.prod seg 2 5 -- cba (left to right)
>>>
Dual hash2 <- ST.prod seg' 0 3 -- abc (right to lett)
>>>
hash1 == hash2
True
Since: 1.1.0.0
RollingHash | |
|
Instances
Constructors
new :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p Source #
\(O(1)\) Creates a one-length RollingHash
from an integer.
Since: 1.1.0.0
unsafeNew :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p Source #
\(O(1)\) Creates a one-length RollingHash
from an integer without taking the mod.
Since: 1.1.0.0