トピックへのリンク:https://www.acwing.com/problem/content/144/
問題の意味:Nの文字列を与えられたS 1 、S 2 ... S N S1を、S2 ... SN、次の照会M回、毎回与えられたクエリ文字列Tは、見つけるSを1 S1を〜S N SNがありT.の接頭どのように多くの文字列です。
思考:これはNトライ・トライの列に挿入することができ、整数ANSノードを記録する文字列の末尾のノード番号である、トライ内の各ノードに格納されています。トライの各お問い合わせについては、
Tを取得するために、ツリーの各ノードのCNT値、検索プロセス中に累積方法は、問い合わせに対する回答であります
#include <cstdioを> する#include <CStringの> する#include <iostreamの> する#include <アルゴリズム> 使用して 名前空間STDを、 INTのトライ[ 1000010 ] [ 30 ]は、B [ 1000010 ]。 int型 TOT = 1 ; チャー [ 1000010します]。 ボイドインサート(char型[]) { int型のn = STRLEN(A)。 int型のp = 1 ; 以下のために(int型 i = 0 ; iがn <I ++の) { int型W = [I] - [ A ' 。 もし(トライ[P] [W] == 0 ) トライ[P] [W] = ++ TOT。 P = トライ[P] [W]。 } B [P] ++ ; 返します。 } int型の楽しみ(char型[]) { int型のn = STRLEN(A)。 INT和= 0、P = 1 。 以下のために(int型 i = 0 ; iがN <、iは++ ) { int型、W = [I] - ' '; もし(トライ[P] [W] == 0 ) 破ります。 P = トライ[P] [W]。 和 + = B [P]。 } 戻り値の和。 } int型のmain() { int型、N M。 scanf関数(" %d個の%のD "、&N、&M)。 以下のために(int型私= 0 ; iがN <; Iは++ ) { scanf関数(" %sの" 、A)。 (a)は、挿入、 } のために(int型のI =0 ; iが<M; iが++ ) { scanf関数(" %sの" 、A)。 int型の合計= 楽しさ(A); printf(" %d個の\ n " 、合計)。 } 戻り 0 。 }