Ex - Taboo Editorial by kyopro_friends


公式解説のステップ2はもう少し簡単にできます。

公式解説で述べられている「\(T_i\)​ と一致するような接尾辞を表すSA上の区間」を探すのは、同じ箇所を2度調べないようにした線形探索で十分です。(\(T_i\) の文字列長昇順で行うと、「今までに見た区間に完全に内包される」「今までに見た区間とはdisjoint」のどちらかしか起こらないので)

以下実装上の工夫を述べます。

\(S,T_i\) に含まれる全ての文字より小さい文字(ここでは @)と、大きい文字(ここでは ~)を用意し、\(X:=T_1+\) @ \(+T_2+\ldots+T_N+\) @ \(+S+\) ~ という文字列に対するSuffix Array及びLCP Arrayを構築します。
このとき、\(X\) の Suffix \(T_i+\) @ \(+\ldots\) に注目すると、これは、\(T_i\) をPrefixに持つような \(S+\) ~ のSuffix の全てより辞書順で小さいことがわかります。したがって、\(T_i\) をPrefixに持つような \(S\) の Suffix は、Suffix Array上でこの後ろを探せば十分です。(区切り文字をこのようにしない場合、前後両方を探索する必要があります)

これを \(|T_i|\) の小さい順に行い、一度見たSuffixにはフラグをつけ、2度見ないようにすることで、\(O(|X|)\) 時間でステップ2を行うことができます。

posted:
last update: