#include <ビット/ STDC ++ H> の#define第Fiの に#define SE第二 の#define INF 0x3f3f3f3f の#define LNF 0x3f3f3f3f3f3f3f3f の#define cin.tie(0); cout.tie(0)FIO IOS :: sync_with_stdio(偽) #定義 pqueue PRIORITY_QUEUE の#define NEW(B)のmemset(A、B、はsizeof(A)) CONST ダブル PI = 4.0 * ATAN(1.0 )。 constの ダブル E = EXP(1.0 ); const int型 MAXN = 4E5 + 8 。 typedefの長い 長いLL。 typedefの符号なしの長いです 長いULL; CONST LLのMOD = 1E9 + 7 。 CONST ULLの基地 = 1E7 + 7 。 CONSTの INTをmaxP = 26 + 5 。 使用して 名前空間はstdを、 構造体Suffix_Node { INT CH【をmaxP]、PAR、LEN。 ボイドのinit(){ NEW(CH、0 ); PAR = LEN = 0 ; } }。 クラスSuffix_Automation { プライベート: Suffix_Node S [MAXN]。 int型のCUR、ラス、SIZ、CRP; 公共: Suffix_Automation():ラス(1)、CUR(1)、SIZ(1)、CRP(1 ){} CONST ボイドのinit(){ ため(int型 I = 0 ; I <= SIZ I ++はS [I) ]。その中に(); ラス = CUR = SIZ = CRP = 1 。 } のconst int型一致(CONST チャー C)のconst { 戻り S [CRP] [C- .CH ' ' ]。 } constのボイドは撤退(のconst int型 LEN){ 一方(CRP =!0 && S [S [CRP] .PAR] .LEN> = LEN)のCRP =のS [CRP] .PAR。 もし(CRP == 0)CRP = 1 。 } CONST ボイド転送(のconst int型 LEN、CONST チャーC){ たCRP = Sは[CRP] [C- .CH ' ' ]。 もし(CRP == 0)CRP = 1 。 (LEN)撤退。 } CONST ボイド ex_tend(CONST チャー C){ // 扩展新字符INT X = C- ' A ' 。 CUR = ++ SIZ。 S [CUR] .LEN = S [ラス] .LEN + 1 。 一方、(LAS =!0 &&!S [ラス] .CH [X]) S [ラス] .CH [X] = CUR、ラス=のS [ラス] .PAR。 もし(LAS == 0)S [CUR] .PAR = 1 。 他に{ int型Q、NQ。 Qが =のS [ラス] .CH [X]。 もし(S [Q] .LEN == S [ラス] .LEN + 1 ) S [CUR] .PAR = Q。 他{ Nqの = ++ SIZ。 S [NQ] = sで、[Q]、S [NQ] .LEN = sで[ T ] .LEN + 1 。 S [CUR] .PAR = sの[Q] .PAR = NQ。 一方、(!= 0 && S [] .CH [X] == Q) S [ザ] .CH [X] = NQ =のS [] .PAR。 } } = CUR。 } } SAM。