フェイス質問
https://www.luogu.org/problem/CF235C
問題の解決策
#include <cstdioを> する#include <CStringの> する#include <iostreamの> する#include <ベクトル> の#define RIレジスタint型 の#define N 1000500 使用して名前空間STDを、 ベクター < INT >息子[N << 1 ]。 BOOL VIS [N << 1 ]。 チャーS [N]。 文字列SS。 int型L0; 構造体SAM { int型 FF [N << 1 ]、LEN [N << 1 ]。 INT CH [N << 1 ] [ 26 ]。 int型 CNT [N << 1 ]。 int型ラス、TOTを。 INT STK [N << 1 ]、トップ。 ボイドのinit(){ ラス = TOT = 1 。 } ボイドが伸びる(int型C){ int型の NP = ++ TOT、P =ラス。ラス= NP。LEN [NP] = LEN [P] + 1 。 一方、(!P && CH [P] [C])CH [P] [C] = NP、Pの=のFF [P]。 CNT [NP] ++ ; もし(!p)はFF [NP]は= 1 ; 他{ INT Q = CH [P]、[C]。 もし(LEN [Q] == LEN [P] + 1)FF [NP] = Q。 他の{ int型 NQ = ++ TOT; 用(RI i = 0 ; iは< 26 ; I ++)CH [NQ] [I] = CH [Q] [I]; FF [NQ] =のFF [Q]。 LEN [NQ] = LEN [P] + 1 。 FF [NP] = FFの[Q] = NQ。 一方、(P && CH [P] [C] == Q)CH [P] [C] = NQ、P = FF [P]。 } } } ボイドmaketree(){ 用(RI i = 1 ; I <= TOT; iが++ )息子[FF [I]一back(I)。 } ボイド treedp(int型X){ 用(RI i = 0 ; I <息子[X] .size(); I ++ ){ treedp(息子[X] [I])。 CNT [X] + = CNT [息子[X] [I]]。 } } 長い 長い(){解決 長い 長い RET = 0 。 int型 = CC 0今= 1。トップ= 0 ; 以下のために(RI I = 0、L = ss.size(); iが1- < 1 ; iは++ ){ int型 C = SSを[I] - [ A ' 。 もし(chは[今] [C]){ CC ++ 。 今= [今] [C] CHであり、 もし(CC> = L0){ 場合(!VIS [今])VIS [今] = 1 [今]、RET + = CNT、STK [++トップ] = 今。 一方、(!今= 1 && LEN [FF [今]]> = L0- 1)今= FFの[今]。CC = LEN [今]。 } } 他{ ながら(今&& CH [今] [C]!)は=のFF [今]。 もし(!今){ 今 = 1 ; CC = 0 。 } 他{ CC = LEN [今] + 1。 今 = CHを[今] [C]。 もし(CC> = L0){ 場合(!VIS [今])VIS [今] = 1 [今]、RET + = CNT、STK [++トップ] = 今。 一方、(!今= 1 && LEN [FF [今]]> = L0- 1)今= FFの[今]。CC = LEN [今]。 } } } } のための(RI I =頂; I> = 1 ; i--)VIS [STKの[I] = 0 ; VIS [ 1 ] = 0 。 リターンRET; } } SAM。 INTのN、M。 INT STK [N << 4]、上; INT メイン(){ sam.init()。 scanf関数(" %sの" 、S); 用(RI I = 0 sam.extend(S [I] - ; iがLに<I ++は、L個の=のSTRLEN(S))' A ' ); sam.maketree(); sam.treedp(1 )。 scanf関数(" %のD "、&N) 用(RI i = 1 ; iが<= N; iは++ ){ CIN >> SSと、L0 = ss.size()。 SS = SS + SS。 COUT << sam.solve()<< ENDL。 } }