. (1) #INCLUDE <cstdio> 2 #INCLUDE <CString을> . (3) #INCLUDE <알고리즘> 4. #INCLUDE <큐> 5. #DEFINE MAXN 5000000 + 10 6. 은 USING 공간 STD] . 7 숯 STR [MAXN * 2 ] . 8 구조체 노드 { . 9 INT 페일; // 불일치 포인터; 10 INT CNT; // 단어의 출현 수, . 11 INT 다음 [ 62이다 ]; // 이 노드의 다음 (SON) (12)이다 } 트리는 [MAXN]; // 노드 구조 이들; 13 INT K = 0 , ANS = 0 ; 14 큐 < INT > Q; // 큐 :; 내장 불일치 포인터 15 무효 build_trie ( INT의 ID, 숯 *의 S) // 즉 ID가 여러 노드를 나타내는 모든 문자, 이러한 문자열 있음 * S 수단; 아래 0 번째 노드에서 스트링을 구축하기 시작 16 { . 17 INT LEN = strlen 함수 (S); // 문자열의 길이 (문자열의 마지막 문자의 깊이에 상당) 18 INT J = 0 ; . (19) 에 대해 ( int로 I = 0 ; I <렌 I ++가이 {) 20 인 - J = S [I]가 ' ' ; 21 인 IF (트리는는 [ID]가 [J] == 다음 내용 0 ) / * 이 경우, 다음에 깊이 문자가 현재 위치에 나타나지 않는다 * / 22이다 { 23이 트리는 [ID] 다음 내용 [J] = K ++; // 현재 노드의 위치 J 문자 노드, 즉, 문자 J의 노드 번호; 24 } 25 ID = 트리는 [ID] 다음 내용 [J]; // 다음 문자로 전달 된 어드레스 ID; 26이다 } 27 트리는 [ID]. ++ CNT; // ++ 단어의 수, 28 } 29 무효 build_fail ( INT의 ID) 30 { 31은 그동안 (! q.empty ()) q.pop는 (); // 보증 용 (큐 두려워는 없다 지우기) (32) 에 대한( 지능 I = 0 ; I는 < 26이고 , I는 ++) // 슈퍼 노드 내의 26 개 문자 이송, 33는 { 34 INT J = 다음 내용 [I] 트리는 [ID] 35 IF (! J = 0 ) { 36 Q .push (J) 37 트리는 [J] ID .fail =; // 첫번째 계층 노드 일치 포인터 포인트 슈퍼 노드이고; 38이다 } 39 } 40 그동안 (! q.empty ()) (41)가 { 42는 INT는 지금 q.front = (); q.pop (); // 현재 위치를 삭제 (큐의 헤드 소자) (43)는 에 대해 ( INT I =0 ; I는 < 26 것은 , I는 ++ ) (44)가 { 45 INT J = 트리는 [현재] 다음 내용 [I] 46은 IF (J의 == 0 ) // 이 노드의 위치 아니며 불일치 포인터 포인트로 전송 노드에서이 편지 노드, 47 { 48 트리는은 [지금] 다음 내용 [I]는 = 트리는 [그래서 답장 [지금] .fail]는 다음 내용 [내가]; // 0 경우, 점 슈퍼 노드에 영향을주지 않습니다; 49 계속 ] // 이 점은 반복 직접 이송 다음 노드로 완료; 50 } 51이고 ; 트리는 [J] = [현재 트리는 [] .fail] 트리는 다음 내용 [I]를 .fail // 이 경우, 현재 위치 문자 노드, 현재의 불일치 위치로 다음 노드 포인터가 불일치 포인터; 52 //문자은 불일치에 대한 포인터의 현재 위치의 노드를 통과하지 않은 경우는 (0, 슈퍼 노드 점)에 영향을주지 않는다 (53)는 (J) q.push; //이 배열로, 54이다 } 55 } 56이다 } (57) 인 공극 solve_trie ( INT의 ID, 숯 *의 S) // 조회 기능; 58 { 59 INT LEN = strlen 함수 (S), J = 0 , 60 대 ( INT I = 0 ; I 렌 <; I는 ++ ) (61)가 { 62 INT J = 트리는 [ID] 다음 내용 [S [I] - ' ' ]; // 다음 노드 위치의 현재 위치; (63)이 그동안 (J && 트리는 [J] .CNT =! - 1. ) // 는 CNT 이송 동안이 노드가 존재하지 않는 경우, 64 { 65 + = 트리는 [J] .CNT ANS; // 검색된 않음 플러스 문자열에 포함되는 단어의 수 66 트리는 [J] .CNT = - 1. ; // 태그 (대신 여러 번 등장의 패턴 문자열의 개수가 등장하기 때문에 참조) 67 J = 트리는 [J]. 실패; // 포인터의 위치를 가리키는 직접 불일치 위치 (즉, 패턴의 문자열 패턴의 문자열의 일부를 삭제 앞이다) (즉, 일치하는 문자열 패턴 실패 찾을) (시간을 절약하기 위해) 68 // 일치에 실패한다 문자열의 앞 부분을 삭제, 사전 트리 패턴 문자열을 설립 69 } 70 ID = 트리는 [ID] 다음 내용 [S [I] - ' ' ]; // ID 승계, 다음 노드의 현재 위치; 0 문제가되지 않습니다 71이다 } 72 } (73)는 지능 () 주 74 { 75 INT , N- 76 는 scanf ( " %의 D " , 및 N-), 77 대 ( INT I = . 1 , I는 <= N-; I는 ++ ) 78 { 79 는 scanf ( " % S " , STR); // i 번째 짧은 스트링; 80 build_trie ( 0 , STR) // 모든 문자열 즉 공통 조상 0 초 루트 노드 () (즉,)에서 내장 0 81 } // 트라이 설립 완료; 82 build_fail ( 0 ); // 불일치 포인터 구축, 83 는 scanf ( " %의 S " , STR)를; // 입력 문자열 쿼리 요구; 84 solve_trie ( 0 , STR); // 쿼리; 85 의 printf ( " % D \ N- " , ANS); // 출력은 86 반환 0 , 87 } 88 // https://www.luogu.org/problemnew/solution/P3808 89 // 도 함께 좋아진다