クラシックタイトル
=現在の文字がCURと一致した場合++、現在のCUR記録長のマッチのS列SAMに対するTストリング、およびトラバーサルT文字としてトライ、一致した(ここで、直接使用しないCUR:照合時間ことに注意してください【今】LEN)と一致CUR = LENまでのリンクポインタとのミスマッチのためにその逆[今]
直接CURない= LEN [今]試合は、機械が自動的にバックにプラス文字に転送されているので?成功しているが、LENは、各ノードは、ノードのmaxlenで表現されているので、先頭の文字なしで保証されていないのはなぜ
ノードの不一致によって表される最短ラン長がlenたので、ミスマッチが正常でlen = CUR前に転送することができる[今]、[今] +1は、すなわち状態に、その文字列でなければならないT MINLEN [今]長さ、[今]状態へのリンクポイントをmaxlenを= MINLEN [今-1]の条件を満足する必要があります!
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 #define MAXN 250005 構造体SAM { int型のCNT、最後。 INT NXT [MAXN << 1 ] [ 26 ]。 int型のリンク[MAXN << 1 ]; INT LEN [MAXN << 1 ]。 SAM(){ CNT =最後= 1 。 } ボイドインサート(INT C){ int型、P =最後に、NP =最後= ++ CNT。 LEN [NP] = LEN [P] + 1 。 以下のための(!; P && NXT [P] [C]; P =リンク[P]) NXT [P]、[C] = NP。 もし(!pは){リンク[NP] = 1。返す;} int型 Q = NXT [P]、[C]。 もし(LEN == LEN [Q] [P] + 1){リンク[NP] = Q。返す;} int型クローン= ++ CNT; リンク[クローン] = リンク[Q]。 LEN [クローン] = LEN [P] + 1 。 memcpy(NXT [クローン]、NXT [Q]、はsizeof NXT [Q])。 リンク[Q] =リンク[NP] = クローン。 用(; P && NXT [P] [C] == Q; P = リンク[P]) NXT [P]、[C]= クローン; } int型の照会(チャー *のS){ int型今= 1、レン= strlenを(S)、CUR = 0、最大= 0 。 以下のために(int型私= 0 ; iがレンを<; Iは++ ){ int型、C = S [I] - [ A ' 。 もし(NXT [今] [C]){ 今 = NXT [今] [C]。 CUR ++ ; } 他{ ながら今(今&&!NXT [今] [C])=リンク[今]。 もし(現在){ CUR = LEN [今] + 1 。 今 = NXT [今] [C]。 } 他{ 今 = 1 。 CUR = 0 ; } } マックス = MAX(最大、CUR)。 } 戻りマックス。 } }、P。 チャーS [MAXN]、T [MAXN]。 INT メイン(){ scanf関数(" %sの%sの" 、S、T)。 INT LEN1 = STRLEN(S)。 INT LEN2 = STRLEN(T)。 以下のために(int型 i = 0 ; I <LEN1; iは++ ) p.insert(S [I] - [ A ' ); COUT << p.query(T)<< ENDL。 }