あるtweetから調べた
min suffixの話
uwi
競技プログラマーミートアップ #0
自己紹介
uwi (うゐ)
twitter : @uwitenpen
所属 : teamLab
2
あるtweet
3
あるtweet
4
具体的にどうやるの?
例
5
w = “aabaab”
w[0,0]=”a”の辞書順最小の接尾辞(min suffix)は”a”
w[0,1]=”aa” -> “a”
w[0,2]=”aab” -> “aab”
w[0,3]=”aaba” -> “a”
w[0,4]=”aabaa” -> “a”
w[0,5]=”aabaab” -> “aab”
上記を求める。
Suffix Array?
6
3
0
4
1
5
2
aab
aabaab
ab
abaab
b
baab
Suffix Array?
7
3
0
4
1
5
2
aab
aabaab
ab
abaab
b
baab
[0,4]からはじまる
wの最小のsuffixは3(aab)だが、
w[0,4]の最小のsuffixは4(a[b])
Suffix Arrayでの最小値をそのま
ま答えに出来るわけではない。
Suffix Array?
8
3
0
4
1
5
2
aab
aabaab
ab
abaab
b
baab
[0,4]からはじまる
wの最小のsuffixは3(aab)だが、
w[0,4]の最小のsuffixは4(a[b])
Suffix Arrayでの最小値をそのま
ま答えに出来るわけではない。
未知のアルゴリズムの予感!!
Lyndon Factorization
文字列をLyndon Wordに分割(一意)する。
Lyndon Wordとは、全suffixのうち自分自身が辞書順最小と
なるもの。
daadaadaa → d|aad|aad|a|a
(d≧aad≧aad≧a≧a), (aad≦ad,d)
9
Lyndon Factorization
時間計算量O(n)で可能。
Lyndon Factorizationのコードは探せばすぐに
みつかる(Wikipediaにもある)。
10
min suffix
wそのもののmin suffixは、Lyndon Factorization
の最後のfactorになる。
したがって、すべてのprefixについての
Lyndon Factorizationがあれば
すべてのmin suffixが求められそう。
11
そんなに自明ではない件
a
a|a
aab
aab|a
aab|a|a
aab|aab
12
w=”aabaab”
仕切りが現れたり
消えたりする
Lyndon Wordは先頭の文字以上の文字しか持っていないの
で、そのprefixのfactorizationは通常の文字列のより簡単な
形にできる。
UV | ... | UV | U
まず全体がLyndon Wordの場合は自明にそれ自体がmin
suffix. そうでない場合は、Uをさらにfactorizeする。
でもUが半分以下の長さとはいえ、全体でO(n)にはならないんじ
ゃ・・
13
w’=UV | ... | UV | U を満たすU,Vを探すには、
ある位置xで、xからはじまるsuffixがw’のprefixになってい
ればよい(xは最初の|の直後の位置になる)。
これはZ algorithmをw’にかけておくと各xについてO(1)で
調べることができる。
14
Z algorithm
各iについて、wのi文字目以降とwとの共通prefixの長さを格
納した配列をO(n)でつくるアルゴリズム。
w=”aabaab”
z_w=[6,1,0,3,1,0]
i=4では”ab”と”aabaab”の共通prefixは”a”なのでz_w[4]=1.
15
各Lyndon Word Lについて、Z algorithmを適用し、
任意のy≦|L|について、
1≦x≦yかつz[x]+x≧y を満たす最小のxを見つければ良い。
x=yのときはL[0,y)はfactorizeされないのでL[0]の位置が答
え。
x<yのときはU=L[0,y%x)になる。すこし横着して(L[0,y-x)
のときの答え)+xになる。
16
例のO(n)のアルゴリズム
wのLyndon Factorizationを求める。
各Lyndon Word Lについて
Z algorithmでz[]を求める。
reach:=0,argmax:=-1
y=1→|L|-1
reach>=yなら求めるxはargmaxで、そうでなければyである。x=yのと
きはL[0]の位置が答え。x<yのときは(L[0,y-x)のときの答え)+xになる。
z[y]+y > reachならreach:=z[y]+y, argmax:=yとする。
y=0のはL[0]の位置が答え。
17
例
w=”aabaab”
LyndonFactorization(w)=aab|aab
z_“aab”=[3,1,0]
minsuffixlen=[1,1,3,1,1,3]
18
他の問題
・実はmax suffixのほうが簡単。これもO(n).
・全体に対するmin rotationもO(n)で求められる。
・任意の連続部分文字列に対するmin suffixは、Suffix Array
を使って前処理O(nlog n), クエリO(1)でできるらしい。
・任意の連続部分文字列に対するmax suffixは前処理O(n),
クエリO(1)でできるらしい。
19
参考文献
・Duval, Jean-Pierre (1983), "Factorizing words over an ordered alphabet", Journal of Algorithms 4 (4)
・Apostolico, A., and Crochemore, M., Optimal canonization of all substrings of a string, Information
and Computation 95, 1 (1991): 76--95.
・Maxim A. Babenko, Pawel Gawrychowski, Tomasz Kociumaka, Tatiana A. Starikovskaya:
Computing Minimal and Maximal Suffixes of a Substring Revisited. CPM 2014: 30--39
・https://twitter.com/climpet/status/598440489935769601
20

あるTweetから調べたmin suffixの話

Editor's Notes

  • #3 戦績を書こうと思ったが大きな大会で特に入賞していないので書きませんでした
  • #4 あとで説明するので割りと早めに
  • #19 時間がなければ飛ばして良い