a d a combine, e s= a b r a c • 要約は、元の文字列の「連結 (++) 」という構造を保存している – 文字列の連結を、ハッシュ値同士の計算として再現できる性質を持つハッシュ関数を使う – H(x)=(hash(x),∣x∣) とすると H(x ++ y) = H(x) combine H(y) • 要約二点の合成 ・・・ 部分文字列のハッシュ – このハッシュを「部分文字列一致判定」と意味解釈できる – 要約で比較するから、計算量が下がる (O(1))
$ map Sum xs x = rangeFoldPT (l, r) s ローリングハッシュ let rh = fromStringRH (1, n) s h = rangeFoldRH (l, r) rh セグメント木 seg <- newListSeg @VUM.MVector (1, n) $ map Min xs x <- rangeFoldSeg seg (l, r)
map Max xs x = rangeFoldSP (l, r) s Zobrist Hash gen <- newStdGen let t = newTableZHMS gen xs z = fromListZHMS (1, n) t xs x = rangeFoldZHMS (l, r) z rangeFold は「区間を、その代数の意味で要約する」インターフェース