解法
まず、
文字目の次に
という文字が現れるインデックスの最小値
を計算します。
これは、という更新を行えばよいです。
さて、
文字目を先頭で使った際にできる、部分文字列の種類数
というDPを考えます。
文字目を使った際に考えられるパターンは、
文字目の1文字のみ
文字目の次に、
という文字を繋げる
の2つです(後者は最大26通りありますが…)。前者は明らかにトータル1通りです。
後者については、の直後に現れる
を取ってくると、
番目の文字の次に
を置いたパターンの部分文字列が網羅できます。
なので、結局
という遷移になります。
では、最終的に求めたい文字列はどうなるでしょうか。
まず、先頭の文字がa,b,...zであるような部分文字列全てについて足してもにならない場合は、明らかに
Eelとなります。
それ以外の場合は、前から貪欲、aから順番に見ていき、総和が以上になるならその文字を選択…という操作を繰り返します。
実装の際は、先頭にダミーの文字を入れると実装が少し楽になります。
今見ているインデックスをとして、次に選ぶ文字を
aから順番に見ていきます。を見て、これが
以上ならば
が次の文字になります。そうでなければ、
から
を引き、次の文字をチェックしていきます。
今見ている文字が最後の場合となるパターンをから引き忘れないようにすれば、答えが求まります。
感想
最近ABCやその他の場所で、ある状態を構成し数え上げる際に重複するパターンを、貪欲にチェックする操作のみ考慮することで重複を消す、という考え方を使ってきたので、それと似たような考え方でできました。
それよりむしろ、メモリ制限が厳しかったです…空間計算量はまだまだ難しいですね