トピックへのリンク:https://www.luogu.org/problem/P5410
質問の意図されて:二つの文字列、Bに、接尾辞aのそれぞれの最大プレフィックス長を求めているB
分析:(また、Z-アルゴリズムアルゴリズムとして知られている)拡張KMP裸タイトル
よりよく説明するためのブログ:https://www.luogu.org/blog/lc-2018-Canton/solution-p5410
しかし、彼はいくつかの問題について話しましたいくつかの場所は、内部の主ケース2には、があります
まず、スタートS [K + L]は間違いなくPの背面、明らかです
ケース2赤、青、緑と同じ、赤ではありません三行の配列を決定し、緑はまだ同じですが、待つことはありません青い線が、この時に自分自身を見てみましょう
#include <ビット/ STDC ++ H.> 使用して 名前空間STD; typedefの長い ロングLL; のconst int型 MAXN = + 1E5 7。 ; // 語間独自のシンボル、わずかに拡大追加 CONST LL INF = 1E18と、 の#define meminf(A)のmemset (A、は0x3F、はsizeof(A)) の#define MEM0(A)のmemset(A、0、はsizeof(A)); char型、B [MAXN]、[MAXN]を INT NXT [MAXN]、[MAXN]拡張。// NXT [I]代表B [I ... LEN]及びbは最大プレフィックス長であるが、伸びる[I]の代表[I ... LEN]と最大プレフィックス長のB ボイドgetnxt(){ int型 LEN = STRLEN (B); NXT [ 0 ] = LEN; //[0] LENのために、自然に、NXT元の文字列の場合である INT今= 0 ; ながら([今] == B [今+ B 1。 ]今&& + 1。 <LEN)今++ ; NXTは[ 。1 ] = 今; INT P0 = 1 ; // P0が満たさP0のNXT [P0] -1 +極大点、初期化の始まりである。 ため(int型 I = 2 ; IはLEN <; Iは++ ){ IF(IはNXTを+ P0-I] <+ P0 NXT [P0])NXT [I] = NXT [I- P0]; // I + 1をkに対応し、NXT [I- P0]はLに相当する(NXT [K-P0 + 2) 列が0であります彼はスタートし、わずかな増加1を開始しているブログとの違い 他の{ int型になりましたNXT = P0 + [P0] - I; 今 = MAX(今、0); // 防止iは后面のp的に在 ながら今(B [今] == B [今+] &&今<LEN +)++ ; NXT [i]は = 今; P0 = I; // 更新P0 } } } ボイドexkmp(){ getnxt()。 INT LEN = STRLEN(A)。 int型になりました= 0 ; 一方、([今] == B [今] &&今<分(STRLEN(A)、(B))strlenを)今++ 。 延び[ 0 ] = 今。 int型 P0 = 0 ; 以下のための( int型i = 1 ; iがLEN <; Iは++ ){ 場合(iはNXTを+ [I-P0] <[P0] + P0を拡張)延び[I] = NXT [1- P0]。 他{ INT今= P0 +延び[P0] - 私。 今 = MAX(今、0 ); ながら ++今(bは[今] ==今<STRLEN(B)&& iは<LEN NOW + && [私は今+]) 。 延び[I] = 今。 P0 = I; } } } int型のmain(){ scanf関数(" %sの%sの" A、B)。 exkmp(); 以下のための(int型 i = 0 ; iは(b)のstrlenを<; iは++)のprintf(" %dの" 、NXT [I])。 putchar(' \ nを' ); 以下のために(int型 i = 0 ; iは、(a)は、strlenを<; iは++)のprintf(" %dの" 延在し、[I])。 putchar(' \ nを' ); リターン 0 ; }